The LCD.h provide with GCB library seems to be written for universal compatibility rather than performance. The character rate is extremely slow given the rates possible by HD44780 and compatible chips.
Attached is a new library, (lcd_opt.h), and a demo program for consideration and testing.
It supports 4 bit and 8 bit modes as well as LAT for chips that need it. 2- bit mode is the same as in the original LCD.H with no changes.
The LCD.h provided with GCB adds unnecessary delays by making the enable pulse 50us instead of a more reasonable 1 or 2us. The specification is a pulse > 600ns.
With the other delays and overhead, the 8-bit mode character rate is a dismal 5847
character per second. In 4 bit mode it is worse at only 4184 characters per second. These speeds are not indicative of the capabilities of the vast majority of HD44780 & compatible LCD displays.
This lcd_opt.h library removes the unnecessary delays by reducing the enable pulse to a more reasonable 1.5us, and then adding a definable speed so that the time between characters is either 50us (default), or 100us if LCD_SLOW is defined in the main program. This give two possible (very precise) character rates: 20,000 chars per second or 10,000 chars per second.
The 50us default delay is 13us greater than the recommended minimum of 37.5 us and should work with any HD44780 compatible controller. If a particular controller cannot handle this speed, then it is NOT HD44780 compatible and it likely a cheap knockoff.
For these cheap knockoffs, a define can be added to the main program.
#define LCD_SLOW
This will reduce the character rate to 10K characters per second, which is still about two times faster than LCD.h. and well within the capabilities of even cheap displays with HD44780 knockoffs.
With LCD_SLOW NOT defined, the character rate is now a respectable 20K characters per second in both 4-bit and 8-bit modes. No changes were made to 2 bit mode.
lcd_opt.h has been tested with PIC16F690 at 8 MHz and with PIC16F829 at 32MHz.
Any PIC operating at over 16MHz should use LAT.
The display used for testing was a Newhaven 16x2 with an ST7066U Controller.
Test measurements were made with a Saleae Logic Analyzer and/or a TEK THS730A Oscilloscope.
Last edit: William Roth 2014-07-08
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I am adding a few extra features like LCD_OFF and LCD_ON, and am considering modifying the define so that there are three speeds instead of two. LDCFAST, LCD_MEDUIM, and LCD_SLOW, where FAST is 20K CPS, MEDIUM is 10K CPS, and SLOW is 5K CPS. The default will be LCD_Medium if the Define is omitted. There are also some more unnecessary delays in other subroutines that can be removed or reduced.
If there is anything else that anyone wants in the 8-bit and 4-bit routines, let me know and I will try to include them.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
"Please look at the new help - we may have LCD_OFF, LCD_ON. They are cursor commands. I may be wrong but please check."
.
What new help are you referring to?
The current "LCDOFF 3" as defined in LCD.H does not turn off the LCD. It should be 8 for off and 12 for on if that is what is intended. There is no define for either LCD_ON or LCD_OFF that I can find.
Question: How do you post GCB code here and maintain formatting? I can't figure it out.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Anonymous
-
2014-07-09
William, I really appreciate the work you've shared recently, and also the quality of your writing. Thanks!
I wrote my own LCD routines several years ago and used these defines for the various command options. Perhaps they'll suggest something useful.
#define clrHome = 1 ;clear the display, home the cursor
#define home = 2 ;home the cursor only
#define RtoL = 4 ;print characters right to left
#define insR = 5 ;insert characters to right
#define LtoR = 6 ;print characters left to right
#define insL = 7 ;insert characters to left
#define lcdOff = 8 ;LCD screen off
#define lcdOn = 12 ;LCD screen on, no cursor
#define curOff = 12 ;an alias for the above
#define block = 13 ;LCD screen on, block cursor
#define under = 14 ;LCD screen on, underline cursor
#define undblk = 15 ;LCD screen on, blinking and underline cursor
#define left = 16 ;cursor left
#define right = 20 ;cursor right
#define panR = 24 ;pan viewing window right
#define panL = 28 ;pan viewing window left
#define mode1 = 32 ;one-line mode (4-bit data)
#define mode2 = 40 ;two-line mode (4-bit data)
#define bus4 = 32 ;4-bit data bus mode
#define bus8 = 48 ;8-bit data bus mode
#define line1 = 128 ;go to start of line 1
#define line2 = 192 ;go to start of line 2
I could be wrong, but I suspect the 2 X 16 display is the most commonly used. If so, it might be good to have the code default to that at start-up. I keep forgetting that the current version defaults to one-line, and end up wasting a few minutes wondering why I'm not seeing the second line!
Thomas Henry
Last edit: Anonymous 2014-07-09
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Before releasing this, I need to add/change a couple of things. The fast mode is just a bit too fast for some chips. I had some corrupted characters using a PIC16F1788 @ 16 mhz at the default speed. So there will be three possible settings. LCD_fast, LCD_medium, and LCD_Slow. This should cover all chips for compatibility.
I also want to review the default initialization settings as they seem rather odd and non-standard. Thomas, indicated that the default was 8x1, but It seems to me to be 16X2 now. I could possibly add defines for initialization such as define LCD_16X2, LCD_20X4, LCD_8x1, etc so that users do not have to edit the LCD.h file or send special commands.
This should be ready in a few days.
William
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I have changed the timings a bit and added new defines. These are:
LCD_Speed Medium // ~ 20K characters per second @ 32 Mhz
LCD_Speed Fast // ~ 15K characters per second
LCD_Speed Slow // ~ 10K characters per second
The Fast speed could be tweaked to be faster, however at 20K chars per second it is about 4 times faster than LCD.H, and should be fast enough.
If there is no LCD_Speed defined, the speed will default to slow.
Also added are subs for LCD_ON and LCD_OFF.
No timing changes were made to 2-bit mode or to the LCDNormalReadByte function.
I have tested on PIC16F1788 with LAT with no problems. This needs to be further tested on a other PICS at various speeds. If you can test in 8-bit mode that would be great. I want to make sure that it defaults to 2 line mode.
Attached is a zip file with the LCD_ALTB.H library as well as the main program file I used for testing.
Tests
1. ChipIno with 16F1938 up to 32Mhz (therefore with LAT) in 4 bit mode - OK
2. PIC40 dev board 16F1939 up to 32Mhz (therefore with LAT) in 4 bit mode - OK
3. PIC40 dev board 16F1939 up to 32Mhz with NO LAT in 8 bit mode - OK
4. PIC40 dev board 16F1939 at 32Mhz with LAT in 8 bit mode - Not Working.
I think there is an issue with 'use case 4', therefore, with LAT in 8 bit mode. Do you want me to investigate?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
@William. Of course. The issue was related to a power-on/reset issue. When programming with LAT/32 all was ok, but, when I power reset the LCD the initialisation was not correct - got 16 black characters.
I have investigated this morning and this can be resolved by changing the init commands at line 120 as follows:
Can you have a look and confirm that these are the correct init commands for the LCD? I have used the information fro a HD44780U datasheet to make these corrections.
And, I have just tested on a ST7920 LCD. All works OK. The ST7920 supports Mandarin and Cyrillic. The config was 16F877a @ 20mhz/NoLAT.
To support the double byte addressing you have to change the LCD 'locate' command as follows by added in the following function then you can you the standard LCD code to drive this complex GLCD display.
So cool!
Anobium
#define locate ST7920Locate
Sub ST7920Locate( In PrintLocX , In PrintLocY )' DESCRIPTIONS:' Place a character to the GLCD controller on the specified row and column.
' Due to the design of the ST7920 controller (to accomodate Mandarin and Cyrillic), you must place the text on the column' according to the numbers above the diagram below:''|--0--|--1--|--2--|......|--7--|' +--+--+--+--+--+---------------------+'|H |e |l |l |o |...|<- row 0(address 0x80)' +--+--+--+--+--+---------------------+'|T|h |i |s ||i ...|<- row 1(address 0x90)' +--+--+--+--+--+---------------------+'|' |'|' |'|' |'...|<- row 2(address 0x88)' +--+--+--+--+--+---------------------+'|-|-|-|-|-|-...|<- row 3(address 0x98)' +--+--+--+--+--+---------------------+'' Example:' Writing 'a' onto the 1st column, and 1st row:' |--0--|--1--|--2--|... ...|--7--|'+--+--+--+--+--+---------------------+' | | | | | | ... | <- row 0 (address 0x80)'+--+--+--+--+--+---------------------+' | | |a | | | ... | <- row 1 (address 0x90)'+--+--+--+--+--+---------------------+' | | | | | | ... | <- row 2 (address 0x88)'+--+--+--+--+--+---------------------+' | | | | | | ... | <- row 3 (address 0x98)'+--+--+--+--+--+---------------------+
select case PrintLocY
case 0
col = PrintLocX OR 0x80
case 1
col = PrintLocX OR 0x90
case 2
col = PrintLocX OR 0x88
case 3
col = PrintLocX OR 0x98
case else
col = PrintLocX OR 0x80
end select
SET LCD_RS OFF
LCDWriteByte (col)
end sub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Seems as if I forgot to include the "wakeup" routine in the 8-bit section. Typically this is done by sending 0x30 once. pause 5ms then again 2 more times with > 160 us spacing. Then 2 line mode is enabled by sending 0x38 ...
So what I have done is create separate sections for 4-bit and 8-bit initialization. This makes it clearer to read/understand.
I have also used hex values instead of binary to maintain constancy with the 2-bit initialization, and because SynWrite erroneously colors binary in green as if it is a comment, making things confusing.
I will attached the updated file after a bit more testing
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I updated the header in LCD_ALTC.h (see the posting above). May I ask that you merge this header into your next release? This will prepare the new file for release as a main stream piece of code.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Attached is LCD_ALTd.h for review. I tested using 16F1788 in 4 & 8bit modes using both LAT no LAT. Tested at processor speeds of 8,16 and 32Mhz with no problems.
Please check the header and make any necessary changes.
@William. I will test again, revise the documentation etc.
To help me. What new commands are now available? And, what new or old methods (subs) are considered private, the subs we would not publish in the Help File?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
. New Defines:
LCD_SPEED FAST
LCD_SPEED MEDIUM
LCD_SPEED SLOW
New Commands:
LCD_OFF
LCD_ON
There are no old or new subs that would now be considered private, meaning that the only needed changes to the help file are related to the above defines and commands.
If LCD_SPEED is not defined, the character spacing will default to about 100 us, giving a speed of approximately 10K characters per second, (more or less) depending upon processor speed.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
@William. As I was updating the Help File I have found that the name convention of the new methods is different from the others, so, I hope you do not mind but the new commands are:
New Defines:
LCD_SPEED FAST
LCD_SPEED MEDIUM
LCD_SPEED SLOW
New Commands:
LCDOff
LCDOn
I changed purely to keep in line with the other command set.
Thank you.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The LCD.h provide with GCB library seems to be written for universal compatibility rather than performance. The character rate is extremely slow given the rates possible by HD44780 and compatible chips.
Attached is a new library, (lcd_opt.h), and a demo program for consideration and testing.
It supports 4 bit and 8 bit modes as well as LAT for chips that need it. 2- bit mode is the same as in the original LCD.H with no changes.
The LCD.h provided with GCB adds unnecessary delays by making the enable pulse 50us instead of a more reasonable 1 or 2us. The specification is a pulse > 600ns.
With the other delays and overhead, the 8-bit mode character rate is a dismal 5847
character per second. In 4 bit mode it is worse at only 4184 characters per second. These speeds are not indicative of the capabilities of the vast majority of HD44780 & compatible LCD displays.
This lcd_opt.h library removes the unnecessary delays by reducing the enable pulse to a more reasonable 1.5us, and then adding a definable speed so that the time between characters is either 50us (default), or 100us if LCD_SLOW is defined in the main program. This give two possible (very precise) character rates: 20,000 chars per second or 10,000 chars per second.
The 50us default delay is 13us greater than the recommended minimum of 37.5 us and should work with any HD44780 compatible controller. If a particular controller cannot handle this speed, then it is NOT HD44780 compatible and it likely a cheap knockoff.
For these cheap knockoffs, a define can be added to the main program.
This will reduce the character rate to 10K characters per second, which is still about two times faster than LCD.h. and well within the capabilities of even cheap displays with HD44780 knockoffs.
With LCD_SLOW NOT defined, the character rate is now a respectable 20K characters per second in both 4-bit and 8-bit modes. No changes were made to 2 bit mode.
lcd_opt.h has been tested with PIC16F690 at 8 MHz and with PIC16F829 at 32MHz.
Any PIC operating at over 16MHz should use LAT.
The display used for testing was a Newhaven 16x2 with an ST7066U Controller.
Test measurements were made with a Saleae Logic Analyzer and/or a TEK THS730A Oscilloscope.
Last edit: William Roth 2014-07-08
Here is the include file and a test program
Last edit: William Roth 2014-07-08
Excellent. I will test as soon as practical.
Thank you.
I am adding a few extra features like LCD_OFF and LCD_ON, and am considering modifying the define so that there are three speeds instead of two. LDCFAST, LCD_MEDUIM, and LCD_SLOW, where FAST is 20K CPS, MEDIUM is 10K CPS, and SLOW is 5K CPS. The default will be LCD_Medium if the Define is omitted. There are also some more unnecessary delays in other subroutines that can be removed or reduced.
If there is anything else that anyone wants in the 8-bit and 4-bit routines, let me know and I will try to include them.
Keep at it please.
Please look at the new help - we may have LCD_OFF, LCD_ON. They are cursor commands. I may be wrong but please check.
Anobium Posted:
.
What new help are you referring to?
The current "LCDOFF 3" as defined in LCD.H does not turn off the LCD. It should be 8 for off and 12 for on if that is what is intended. There is no define for either LCD_ON or LCD_OFF that I can find.
Question: How do you post GCB code here and maintain formatting? I can't figure it out.
William, I really appreciate the work you've shared recently, and also the quality of your writing. Thanks!
I wrote my own LCD routines several years ago and used these defines for the various command options. Perhaps they'll suggest something useful.
I could be wrong, but I suspect the 2 X 16 display is the most commonly used. If so, it might be good to have the code default to that at start-up. I keep forgetting that the current version defaults to one-line, and end up wasting a few minutes wondering why I'm not seeing the second line!
Thomas Henry
Last edit: Anonymous 2014-07-09
This new LCD driver is great. I have tested today using a Chipino shield (see http://www.chipino.com/) as the chipset and LCD driver.
All works great!
Do you have a later build you want me to review and include in the next GCB build?
I will update the documentation and the copyright header.
Anobium
Before releasing this, I need to add/change a couple of things. The fast mode is just a bit too fast for some chips. I had some corrupted characters using a PIC16F1788 @ 16 mhz at the default speed. So there will be three possible settings. LCD_fast, LCD_medium, and LCD_Slow. This should cover all chips for compatibility.
I also want to review the default initialization settings as they seem rather odd and non-standard. Thomas, indicated that the default was 8x1, but It seems to me to be 16X2 now. I could possibly add defines for initialization such as define LCD_16X2, LCD_20X4, LCD_8x1, etc so that users do not have to edit the LCD.h file or send special commands.
This should be ready in a few days.
William
@William. Ok.
See if you can consume https://sourceforge.net/p/gcbasic/discussion/629990/thread/b0fc3347/#6a00 also.
I did have an issue with timing at 16mhz but no issue at 32mhz with LAT.
Let me know when you are ready for the next set of tests.
Anobium
I have changed the timings a bit and added new defines. These are:
The Fast speed could be tweaked to be faster, however at 20K chars per second it is about 4 times faster than LCD.H, and should be fast enough.
If there is no LCD_Speed defined, the speed will default to slow.
Also added are subs for LCD_ON and LCD_OFF.
No timing changes were made to 2-bit mode or to the LCDNormalReadByte function.
I have tested on PIC16F1788 with LAT with no problems. This needs to be further tested on a other PICS at various speeds. If you can test in 8-bit mode that would be great. I want to make sure that it defaults to 2 line mode.
Attached is a zip file with the LCD_ALTB.H library as well as the main program file I used for testing.
Looking good with one error.
Tests
1. ChipIno with 16F1938 up to 32Mhz (therefore with LAT) in 4 bit mode - OK
2. PIC40 dev board 16F1939 up to 32Mhz (therefore with LAT) in 4 bit mode - OK
3. PIC40 dev board 16F1939 up to 32Mhz with NO LAT in 8 bit mode - OK
4. PIC40 dev board 16F1939 at 32Mhz with LAT in 8 bit mode - Not Working.
I think there is an issue with 'use case 4', therefore, with LAT in 8 bit mode. Do you want me to investigate?
I am not sure what 'not working' means. Corrupted characters? No display ?
Can you please describe the problem /symptoms?
@William. Of course. The issue was related to a power-on/reset issue. When programming with LAT/32 all was ok, but, when I power reset the LCD the initialisation was not correct - got 16 black characters.
I have investigated this morning and this can be resolved by changing the init commands at line 120 as follows:
Can you have a look and confirm that these are the correct init commands for the LCD? I have used the information fro a HD44780U datasheet to make these corrections.
But, looks MUCH faster! Well done.
I have attached my current LCD file, LCD_ALTc.h
I have just re-compiled my serial LCD devices to use the new code. 4bit/LAT @ 32mhz on 16f1847.
All works great and much faster updating.
Thank you.
And, I have just tested on a ST7920 LCD. All works OK. The ST7920 supports Mandarin and Cyrillic. The config was 16F877a @ 20mhz/NoLAT.
To support the double byte addressing you have to change the LCD 'locate' command as follows by added in the following function then you can you the standard LCD code to drive this complex GLCD display.
So cool!
Anobium
Good Catch there Anobium,
Seems as if I forgot to include the "wakeup" routine in the 8-bit section. Typically this is done by sending 0x30 once. pause 5ms then again 2 more times with > 160 us spacing. Then 2 line mode is enabled by sending 0x38 ...
So what I have done is create separate sections for 4-bit and 8-bit initialization. This makes it clearer to read/understand.
I have also used hex values instead of binary to maintain constancy with the 2-bit initialization, and because SynWrite erroneously colors binary in green as if it is a comment, making things confusing.
I will attached the updated file after a bit more testing
Thank you.
I updated the header in LCD_ALTC.h (see the posting above). May I ask that you merge this header into your next release? This will prepare the new file for release as a main stream piece of code.
@Anobium
Attached is LCD_ALTd.h for review. I tested using 16F1788 in 4 & 8bit modes using both LAT no LAT. Tested at processor speeds of 8,16 and 32Mhz with no problems.
Please check the header and make any necessary changes.
Feel free to rename the file if necessary.
Last edit: William Roth 2014-08-17
@William. I will test again, revise the documentation etc.
To help me. What new commands are now available? And, what new or old methods (subs) are considered private, the subs we would not publish in the Help File?
.
New Defines:
LCD_SPEED FAST
LCD_SPEED MEDIUM
LCD_SPEED SLOW
New Commands:
LCD_OFF
LCD_ON
There are no old or new subs that would now be considered private, meaning that the only needed changes to the help file are related to the above defines and commands.
If LCD_SPEED is not defined, the character spacing will default to about 100 us, giving a speed of approximately 10K characters per second, (more or less) depending upon processor speed.
Uploaded to the released code section of SourceForge, see https://sourceforge.net/p/gcbasic/code/HEAD/tree/GCBASIC/trunk/include/lowlevel/lcd.h
I have updated header for copyright etc. This is now destined for general release. I will update the Help File as soon as practical.
New Defines:
LCD_SPEED FAST
LCD_SPEED MEDIUM
LCD_SPEED SLOW
New Commands:
LCD_OFF
LCD_ON
Thank you!!
@William. As I was updating the Help File I have found that the name convention of the new methods is different from the others, so, I hope you do not mind but the new commands are:
New Defines:
LCD_SPEED FAST
LCD_SPEED MEDIUM
LCD_SPEED SLOW
New Commands:
LCDOff
LCDOn
I changed purely to keep in line with the other command set.
Thank you.
@All. Reposted LCD.H. Typo fixed in method title.
@Anobium
The LCD.H file referred to three posts up is not the latest version (LCD_ALTd.h). The version at the mentioned link: https://sourceforge.net/p/gcbasic/code/HEAD/tree/GCBASIC/trunk/include/lowlevel/lcd.h does not support LCD_SPEED or LCDOn/LCDOff.
The latest version should have a sub-header dated 8-17-2014