Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : Sample of 4x20 LCD & SubRoutines
Page 1 of 2 | |||||
Author | Message | ||||
Ray B Senior Member Joined: 16/02/2007 Location: AustraliaPosts: 219 |
This is my first attempt of converting some original LCD code that can select the type of LCD (e.g. 16 x 2 or 20 x 4) and send strings to a 20 x 4 LCD. The original code is based upon Geoff's & James work but with a lot of other message examples that I have previously documented & I've just broken a lot of it up into sub routines. Down in lines 30100 - 30160 I've even got nested subroutines that seem to work. YES this code is rough but is only proof of a concept at this stage. 10 ' DEMONSTRATION OF MM DRIVING LCDs USING SUBROUTINES 15 ' based on the original 16 X 2 code by Geoff Graham, March 2011 20 ' & later work by James Deakins July 2011 30 ' This code had a lot of extra comments / code added by myself Ray Bright (RayB) 40 ' as well as use of subroutines that become available in MM3.1 41 ' 42 ' After the initial lines are displayed the program goes off and does all sorts of 43 ' display gymnastics to demonstrate possible display options 45 ' If you use this code for a specific application then just strip out all of the 46 ' unrequired comment lines and demo code 50 ' ************************************************************ ********************* 55 ' 100 ' ************************************************************ ********************* 110 ' * HARDWARE DRIVER & CONNECTION ISSUES * 120 ' * This relates to standard 16 X 2 and 20 X 4 LCDs * 130 ' * TO USE: * 140 ' * - Set up your text messages and number of lines / char for your LCD * 150 ' * - execute GOSUB 11000 to initialise display * 160 ' * - execute GOSUB 12000 to display the text in lines * 170 ' * LCD_line1$, LCD_line2$, (and LCD_line3$ and LCD_line4$) * 175 ' * Make sure you have the right pinouts between MM & LCD correct * 180 ' * or change the code to suit: * 185 ' * Maximite pin 11 is RS, pin 12 is EN. R/W is grounded. * 190 ' * Maximite pins 13 to 16 are D4 to D7.<<< May be different to schematic * 195 ' ************************************************************ ********************* 200 ' 205 ' * Edit following lines to set your hardware setup including LCD used * 210 ' ************************************************************ ********************* 215 ' Change these values to match your LCD module 220 _C_Lines = 4 225 _C_LineLength = 20 230 ' You shouldn't have to change the next 4 values 235 _C_L1_Start = 0 240 _C_L2_Start = 64 245 _C_L3_Start = 20 250 _C_L4_Start = 84 255 ' 260 DIM _Offset(4) 265 _Offset(1) = _C_L1_Start ' load all the offsets into an array 270 _Offset(2) = _C_L2_Start 275 _Offset(3) = _C_L3_Start 280 _Offset(4) = _C_L4_Start 285 ' 290 DIM _Text$(4) 292 ' 294 ' Change these values to change the initial display message 296 ' Note: if you have a 20 character display, put spaces on the end to fill 298 ' them out to 20 characters length, othewise you get strange char. displayed. 299 ' 300 _Text$(1) = "Hello World I'm" ' load initial display values for the screen 305 _Text$(2) = "a Maximite LCD " 310 _Text$(3) = "communicating with a" 315 _Text$(4) = "4 line HD44780 LCD. " 320 ' 500 ' ************************************************************ ********************* 510 ' * START OF CODE * 520 ' ************************************************************ ********************* 525 ' 530 InitLCD ' Initialise the LCD 540 SendText ' Send message/s to the LCD 550 END 560 ' 11000 Sub InitLCD 11005 ' ************************************************************ ******************* 11010 ' * INITIALISE THE LCD - refer to LCD manufactures manual * 11015 ' ************************************************************ ******************* 11020 ' 11030 FOR i = 11 TO 16 : SETPIN i, 9 : NEXT i ' set pins as outputs 11040 _LCD_byte = &B0011 : 4Bits : PAUSE 5 ' reset- a 3 byte sequence of 11050 _LCD_byte = &B0011 : 4Bits : PAUSE 5 ' reset of 0011xxxx 11060 _LCD_byte = &B0011 : 4Bits : PAUSE 5 ' reset last of 3 bytes 11070 _LCD_byte = &B0010 : 4Bits : PAUSE 2 ' set LCD to 4 bit mode 11080 _LCD_byte = &B00101100 : SendByte ' 4 bit, 2 lines (or 4 lines) 11090 _LCD_byte = &B00001100 : SendByte ' display on, no cursor 11100 _LCD_byte = &B00000110 : SendByte ' increment on write 11110 _LCD_byte = &B00000001 : SendByte ' clear display 11115 pause 2 11120 End Sub 11130 ' 12000 Sub SendText 12005 ' ************************************************************ ******************* 12010 ' * SEND LINES OF TEXT TO LCD * 12015 ' ************************************************************ ******************* 12020 ' 12030 ' the text is in LCD_Line1$ and LCD_Line2$ 12035 ' and if it's a 4 line LCD, also in LCD_Line3$ and LCD_Line4$ 12038 ' 12040 '_LCD_byte = &B00000001 : SendByte ' to clear display & send 12050 'pause 2 12060 ' 12065 ' *** FOLLOWING IS SOME TEST CODE UNTIL RETURN STATEMENT ***. 12066 ' *** PARTS OF THIS CAN BE DELETED IF YOU WISH *** 12068 ' 12070 ' *** Example of GOTO a screen location on the LCD and write a character. *** 12075 '--------------------------------------------------------- 12080 '_LCD_Line = 2 : _LCD_Col = 4 : LocateCursor ' GOTO L2, C4 12090 '_LCD_byte = ASC("Z") : pin(11) = 1 : SendByte ' Write a char.to show it works 12100 ' 12105 ' *** Example - Turn on a blinking cursor (to see where text is being written) 12106 ' ------------------------------------------------------------ --------- 12110 '_LCD_byte = &B00001111 : SendByte ' Display on, Cursor on, blinking cursor 12120 ' 12125 ' *** Example - Print a non-standard char. from the char. set held on the LCD 12126 ' ------------------------------------------------------------ --------- 12130 '_LCD_byte = &HF4 : pin(11) = 1 : SendByte ' print the ohm symbol 12140 ' ' note that the cursor didn't need to be moved 12145 ' Pause long enough for the tester to see the results 12150 'pause 2000 12160 ' 12162 ' Example - Display the default messages for the lines 12165 ' (as defined at beginning of the code) 12166 ' -------- ------------------------------------------------------------ --------- 12167 ' relies on the correct num. of lines for the LCD being entered into _C_LINES 12168 ' & correct number of characters per line being entered into _C_LineLength. 12169 ' 12170 for _Line_out = 1 to _C_LINES 12180 _LCD_byte = 128 + _Offset(_Line_out) : SendByte 'select the output line on the LCD 12190 for _LCD = 1 to _C_LineLength 12200 _LCD_byte = ASC(MID$(_Text$(_Line_out), _LCD, 1)) 12210 Pin(11) = 1 : SendByte ' send the character 12220 next _LCD 12230 next _Line_out 12240 ' 12250 ' Pause long enough for the tester to see the results 12260 ' --------------------------------------------------- 12270 pause 2000 12300 ' 12310 ' Load a 26 char message into Line 2 (noting that on a 16 / 20 character display 12315 ' we only see the first 16 / 20 characters) 12320 ' ------ ------------------------------------------------------------ --------- 12330 '_LCD_Byte = 128 + _Offset(2) : SendByte 'to start of 2nd line 12340 'TestMsg$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 12350 'for _LCD = 1 to 26 12360 ' _LCD_byte = ASC(MID$(TestMsg$, _LCD, 1)) 12370 ' Pin(11) = 1 : SendByte ' Send the character 12380 'next _LCD 12390 ' 12400 ' the user will now see the first 16 char. of test message displayed on 2nd line 12405 ' 12410 ' Pause long enough for the tester to see the results 12420 ' --------------------------------------------------- 12430 'pause 2000 12500 ' 12510 ' Now shift the message so the balance of the second line can be read 12520 ' ------------------------------------------------------------ ------- 12530 ' 12540 ' _LCD_Line = 2 : _LCD_col = 1 : LocateCursor ' for variety use the LCD LOCATE subroutine 12550 ' for _LCD = 1 to 40 12560 ' _LCD_byte = &B00011000 : SendByte 12570 ' pause 1000 12580 ' next _LCD 12590 ' 12600 ' Note that this shifts both lines left, and you have to shift left 40 times 12610 ' to get back where you started from 12615 '--------------- ------------------------------------------------------------ --------- 12620 ' Also notice how the text changes to different lines as the message is scrolled. 12625 ' 12630 ' Pause long enough for the tester to see the results 12640 ' --------------------------------------------------- 12650 pause 2000 12660 ' 12670 ' Now let's use custom code to scroll only the second line 12680 ' -------------------------------------------------------- 12690 ' 12700 ' 12710 'TestMsg$ = "This is a really long message that we will scroll across the second line of the LCD screen." 12720 'MsgLen = Len(TestMsg$) 12730 'for Mask_Offset = 0 to MsgLen - _C_LineLength ' keep track of where we're starting the display window 12735 ' _LCD_line = 2 : _LCD_col = 1 : LocateCursor ' go to the start of line 2 12740 ' for _LCD = 1 to _C_LineLength 12750 ' _LCD_byte = ASC(MID$(TestMsg$, Mask_Offset + _LCD, 1)) 12760 ' Pin(11) = 1 : SendByte 12770 ' next _LCD 12780 ' if Mask_offset = 0 then pause 2000 else pause 800 ' so screen has time to refresh, and user can read it 12790 'next Mask_Offset 12990 End Sub 12995 ' 30000 Sub SendByte 30005 ' ************************************************************ *********** 30005 ' * SEND a BYTE TO THE LCD * 30010 ' ************************************************************ *********** 30015 ' 30020 ' the data to be sent is in _LCD_byte 30030 ' 30040 PIN(13) = _LCD_byte AND &B00010000 ' output the 1st 4 bits 30050 PIN(14) = _LCD_byte AND &B00100000 30060 PIN(15) = _LCD_byte AND &B01000000 30070 PIN(16) = _LCD_byte AND &B10000000 30080 PIN(12) = 1 : PIN(12) = 0 ' tell lcd to accept data 30085 4Bits 30088 End Sub 30090 ' 30100 Sub 4Bits 30105 ' Entry point to send just 4 bits to the LCD 30110 PIN(13) = _LCD_byte AND &B00000001 ' output the 2nd 4 bits 30120 PIN(14) = _LCD_byte AND &B00000010 30130 PIN(15) = _LCD_byte AND &B00000100 30140 PIN(16) = _LCD_byte AND &B00001000 30150 PIN(12) = 1 : PIN(12) = 0 : PIN(11) = 0 ' tell lcd to accept data 30160 End Sub 30170 ' 30200 Sub LocateCursor 30205 ' Cursor LOCATE code 30210 ' 30220 ' Move cursor to a location on the LCD screen 30240 ' The line is sent in _LCD_Line, the column is sent in _LCD_Col 30250 _Start = _Offset(_LCD_Line) + _LCD_Col -1 30270 _LCD_byte = 128 + _Start : SendByte ' move to the requested location 30280 End Sub RayB from Perth WA |
||||
Ray B Senior Member Joined: 16/02/2007 Location: AustraliaPosts: 219 |
With the freshness of a new morning I just cleaned up this code as below BUT when I remove the line numbers the SubRoutines don't seem to work correctly. 10 ' DEMONSTRATION OF MM DRIVING LCDs USING SUBROUTINES 15 ' based on the original 16 X 2 code by Geoff Graham, March 2011 20 ' & later work by James Deakins July 2011 30 ' This code had a lot of extra comments / code added by myself Ray Bright (RayB) 40 ' as well as use of subroutines that become available in MM3.1 45 ' This revision is a stripped down version to remove extra example code 100 ' ************************************************************ ********************* 110 ' * HARDWARE DRIVER & CONNECTION ISSUES * 120 ' * This relates to standard 16 X 2 and 20 X 4 LCDs * 130 ' * TO USE: * 140 ' * - Set up your text messages and number of lines / char for your LCD * 150 ' * - execute GOSUB 11000 to initialise display * 160 ' * - execute GOSUB 12000 to display the text in lines * 170 ' * LCD_line1$, LCD_line2$, (and LCD_line3$ and LCD_line4$) * 175 ' * Make sure you have the right pinouts between MM & LCD correct * 180 ' * or change the code to suit: * 185 ' * Maximite pin 11 is RS, pin 12 is EN. R/W is grounded. * 190 ' * Maximite pins 13 to 16 are D4 to D7.<<< May be different to schematic * 195 ' ************************************************************ ********************* 200 ' * * 205 ' * Edit following lines to set your hardware setup including LCD used * 210 ' ************************************************************ ********************* 215 ' Change these values to match your LCD module 220 _C_Lines = 4 225 _C_LineLength = 20 230 ' You shouldn't have to change the next 4 values 235 _C_L1_Start = 0 240 _C_L2_Start = 64 245 _C_L3_Start = 20 250 _C_L4_Start = 84 255 ' 260 DIM _Offset(4) 265 _Offset(1) = _C_L1_Start ' load all the offsets into an array 270 _Offset(2) = _C_L2_Start 275 _Offset(3) = _C_L3_Start 280 _Offset(4) = _C_L4_Start 285 ' 290 DIM _Text$(4) 292 ' 294 ' Change these values to change the initial display message 296 ' Note: if you have a 20 character display, put spaces on the end to fill 298 ' them out to 20 characters length, othewise you get strange char. displayed. 299 ' 300 _Text$(1) = "Hello World I'm a " ' load initial display values for the screen 305 _Text$(2) = "LCD interfacing MM " 310 _Text$(3) = "with a 20 x 4 LCD " 315 _Text$(4) = "using Subroutines " 320 ' 500 ' ************************************************************ ********************* 510 ' * START OF CODE - IT A RUNs FROM HERE * 520 ' ************************************************************ ********************* 525 ' 530 InitLCD ' Initialise the LCD 540 SendText ' Send message/s to the LCD 550 END 560 ' 11000 Sub InitLCD 11005 ' ************************************************************ ******************* 11010 ' * INITIALISE THE LCD - refer to LCD manufactures manual * 11015 ' ************************************************************ ******************* 11020 ' 11030 FOR i = 11 TO 16 : SETPIN i, 9 : NEXT i ' set pins as outputs 11040 _LCD_byte = &B0011 : 4Bits : PAUSE 5 ' reset- a 3 byte sequence of 11050 _LCD_byte = &B0011 : 4Bits : PAUSE 5 ' reset of 0011xxxx 11060 _LCD_byte = &B0011 : 4Bits : PAUSE 5 ' reset last of 3 bytes 11070 _LCD_byte = &B0010 : 4Bits : PAUSE 2 ' set LCD to 4 bit mode 11080 _LCD_byte = &B00101100 : SendByte ' 4 bit, 2 lines (or 4 lines) 11090 _LCD_byte = &B00001100 : SendByte ' display on, no cursor 11100 _LCD_byte = &B00000110 : SendByte ' increment on write 11110 _LCD_byte = &B00000001 : SendByte ' clear display 11115 pause 2 11120 End Sub 11130 ' 12000 Sub SendText 12005 ' ************************************************************ ******************* 12010 ' * SEND LINES OF TEXT TO LCD * 12015 ' ************************************************************ ******************* 12020 ' 12030 ' the text is in LCD_Line1$ and LCD_Line2$ 12035 ' and if it's a 4 line LCD, also in LCD_Line3$ and LCD_Line4$ 12038 ' 12040 _LCD_byte = &B00000001 : SendByte ' to clear display & send 12050 pause 200 12060 ' 12065 ' *** FOLLOWING IS SOME TEST CODE UNTIL RETURN STATEMENT ***. 12066 ' *** PARTS OF THIS CAN BE DELETED IF YOU WISH *** 12068 ' 12070 ' *** Example of GOTO a screen location on the LCD and write a character. *** 12075 '--------------------------------------------------------- 12080 '_LCD_Line = 2 : _LCD_Col = 4 : LocateCursor ' GOTO L2, C4 12090 '_LCD_byte = ASC("Z") : pin(11) = 1 : SendByte ' Write a char.to show it works 12095 pause 2000 ' time to observe result 12100 ' 12105 ' *** Example - Turn on a blinking cursor (to see where text is being written) 12106 ' ------------------------------------------------------------ --------- 12110 _LCD_byte = &B00001111 : SendByte ' Display on, Cursor on, blinking cursor 12115 pause 2000 ' time to observe result 12120 ' 12125 ' *** Example - Print a non-standard char. from the char. set held on the LCD 12126 ' ------------------------------------------------------------ --------- 12130 '_LCD_byte = &HF4 : pin(11) = 1 : SendByte ' print the ohm symbol 12140 ' ' note that the cursor didn't need to be moved 12145 pause 2000 ' time to observe result 12160 ' 12165 ' Example - Display the default messages for the lines (defined above) 12166 ' -------- ------------------------------------------------------------ --------- 12167 ' relies on the correct num. of lines for the LCD being entered into _C_LINES 12168 ' & correct number of characters per line being entered into _C_LineLength. 12169 ' 12170 for _Line_out = 1 to _C_LINES 12180 _LCD_byte = 128 + _Offset(_Line_out) : SendByte 'select the output line on the LCD 12190 for _LCD = 1 to _C_LineLength 12200 _LCD_byte = ASC(MID$(_Text$(_Line_out), _LCD, 1)) 12210 Pin(11) = 1 : SendByte ' send the character 12220 next _LCD 12230 next _Line_out 12240 ' 12250 ' Pause long enough for the tester to see the results 12260 ' --------------------------------------------------- 12270 pause 2000 12300 ' 12310 ' Load a 26 char message into Line 2 (noting that on a 16 / 20 character display 12315 ' we only see the first 16 / 20 characters) 12320 ' ------ ------------------------------------------------------------ --------- 12330 _LCD_Byte = 128 + _Offset(2) : SendByte 'to start of 2nd line 12340 TestMsg$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 12350 for _LCD = 1 to 26 12360 _LCD_byte = ASC(MID$(TestMsg$, _LCD, 1)) 12370 Pin(11) = 1 : SendByte ' Send the character 12380 next _LCD 12390 ' 12400 ' the user will now see the first 16 char. of test message displayed on 2nd line 12405 ' 12410 ' Pause long enough for the tester to see the results 12420 ' --------------------------------------------------- 12430 pause 2000 ' time to observe result 12500 ' 12510 ' Now shift the message so the balance of the second line can be read 12520 ' ------------------------------------------------------------ ------- 12530 ' 12540 _LCD_Line = 2 : _LCD_col = 1 : LocateCursor ' for variety use the LCD LOCATE subroutine 12550 for _LCD = 1 to 40 12560 _LCD_byte = &B00011000 : SendByte 12570 pause 1000 12580 next _LCD 12590 ' 12600 ' Note that this shifts both lines left, and you have to shift left 40 times 12610 ' to get back where you started from 12615 '--------------- ------------------------------------------------------------ --------- 12620 ' Also notice how the text changes to different lines as the message is scrolled. 12625 ' 12630 ' Pause long enough for the tester to see the results 12640 ' --------------------------------------------------- 12650 pause 2000 12660 ' 12670 ' Now let's use custom code to scroll only the second line 12680 ' -------------------------------------------------------- 12690 ' 12700 ' 12710 TestMsg$ = "This is a really long message that we will scroll across the second line of the LCD screen." 12720 MsgLen = Len(TestMsg$) 12730 for Mask_Offset = 0 to MsgLen - _C_LineLength ' keep track of where we're starting the display window 12735 _LCD_line = 2 : _LCD_col = 1 : LocateCursor ' go to the start of line 2 12740 for _LCD = 1 to _C_LineLength 12750 _LCD_byte = ASC(MID$(TestMsg$, Mask_Offset + _LCD, 1)) 12760 Pin(11) = 1 : SendByte 12770 next _LCD 12780 if Mask_offset = 0 then pause 2000 else pause 800 ' so screen has time to refresh, and user can read it 12790 next Mask_Offset 12990 End Sub 12995 ' 30000 Sub SendByte 30005 ' ************************************************************ *********** 30005 ' * SEND a BYTE TO THE LCD - SUB ROUTINE SendByte * 30010 ' ************************************************************ *********** 30015 ' 30020 ' the data to be sent is in _LCD_byte 30030 ' 30040 PIN(13) = _LCD_byte AND &B00010000 ' output the 1st 4 bits 30050 PIN(14) = _LCD_byte AND &B00100000 30060 PIN(15) = _LCD_byte AND &B01000000 30070 PIN(16) = _LCD_byte AND &B10000000 30080 PIN(12) = 1 : PIN(12) = 0 ' tell lcd to accept data 30085 4Bits ' call nested sub 4Bits 30088 End Sub 30090 ' 30095 ' 30100 Sub 4Bits 30101 ' ************************************************************ *********** 30102 ' * SEND 4 BITS TO THE LCD - SUB ROUTINE 4Bits * 30103 ' ************************************************************ *********** 30105 ' Entry point to send just 4 bits to the LCD 30110 PIN(13) = _LCD_byte AND &B00000001 ' output the 2nd 4 bits 30120 PIN(14) = _LCD_byte AND &B00000010 30130 PIN(15) = _LCD_byte AND &B00000100 30140 PIN(16) = _LCD_byte AND &B00001000 30150 PIN(12) = 1 : PIN(12) = 0 : PIN(11) = 0 ' tell lcd to accept data 30160 End Sub 30170 ' 30200 Sub LocateCursor 30205 ' ************************************************************ *********** 30210 ' * SUB ROUTINE LocateCursor * 30215 ' ************************************************************ *********** 30220 ' Cursor LOCATE code 30225 ' 30230 ' Move cursor to a location on the LCD screen 30240 ' The line is sent in _LCD_Line, the column is sent in _LCD_Col 30250 _Start = _Offset(_LCD_Line) + _LCD_Col -1 30270 _LCD_byte = 128 + _Start : SendByte ' move to the requested location 30280 End Sub RayB from Perth WA |
||||
James_From_Canb Senior Member Joined: 19/06/2011 Location: AustraliaPosts: 265 |
I've attached a zip file with a revised LCD.BAS. It works with 16 x 2 and 20 x 4 displays, and should work with 8 x 1 and 16 x 1 displays (but I don't have any to test). It also includes a subroutine to locate the cursor on the LCD screen by line and column. I intend to provide an extensive set of LCD routines in the next couple of days. It will be called LCD_LIB.BAS. Please let me know if you find any problems, or have any suggestions. James 2012-02-03_070836_LCD1_1.zip My mind is aglow with whirling, transient nodes of thought careening through a cosmic vapor of invention. Hedley Lamarr, Blazing Saddles (1974) |
||||
Ray B Senior Member Joined: 16/02/2007 Location: AustraliaPosts: 219 |
James I for one find the original allocation of LCD lines clashed with RS232 lines in Geoff's original design & coding e.g. Com1 Tx/Rx clashes with LCD D6 & D7 on I/O pins 15 & 16 so I'm inclined to use other I/O pins in the range I/O 11 - 20 but to do this I'd recommend you inset into the LCDInit or somewere else something like the following in your library code. RS=11 : EN=12 : D4=13 : D5=14 : D6=15 : D7=16 'Allocate pins Of course this will mean through your code you will need to make the following changes e.g. PIN(13) = Data AND &B00000001 and references like it would need to be changed to say the following: PIN(D4) = Data AND &B00000001 Cheers RayB from Perth WA |
||||
djuqa Guru Joined: 23/11/2011 Location: AustraliaPosts: 447 |
I am working a a GENERIC, but more featured LCD Subroutine that implements this. Some of the other features. 1/ .ini file LCD module and Pin allocations defined here. No hard code constants. 2/ Type of display independent 8x1,8x2, 16x2,20x2,40x4 Pre-defined. any other format user-definable. 3/ Support for multiple LCD's running on DM/MM using either shared/seperate pins. I currently have 4 different format LCD's running on DM-Mini at the same time. I am using MMBasic 3.1 & a total of 9 GPIO pins, VK4MU MicroController Units |
||||
Ray B Senior Member Joined: 16/02/2007 Location: AustraliaPosts: 219 |
Would'nt make more sense to form a "LCD working party" to combine thoughts into one common LCD library. This same concept should be used for other librarys that may be commenced e.g. RS232 Working Party. RayB from Perth WA |
||||
James_From_Canb Senior Member Joined: 19/06/2011 Location: AustraliaPosts: 265 |
I think the LCD.BAS demo code should be kept simple and match the LCD.PDF file. I would prefer to leave it as it is, but feel free to submit your own versions. However, redefining pins and other 'advanced' functions are good candidates for LCD_LIB.BAS. That's the file I expect most people to use if they're serious. I'll see what I can whip up. Djuqa: Multi displays, especially with a combination of shared and separate pins are a bit out of the ordinary. I might leave that code to you The .ini file has merit, but the config could just as easily be defined as parameters to the setup subroutine/s, or at the start of the code. IMHO. Which raises an interesting point. LCD_LIB.BAS really needs to be in 2 files - one consisting solely of subroutines, and an initialisation file that uses the subroutines to set everything up. The initialisation code should be merged or inserted into the main program. Any suggestions on a naming convention? James My mind is aglow with whirling, transient nodes of thought careening through a cosmic vapor of invention. Hedley Lamarr, Blazing Saddles (1974) |
||||
djuqa Guru Joined: 23/11/2011 Location: AustraliaPosts: 447 |
Sounds good Ray, [quote=James from Cold Country] The .ini file has merit, but the config could just as easily be defined as parameters to the setup subroutine/s, or at the start of the code. IMHO. [/quote] Config.ini is a better idea for the following reasons 1/ Each user con modify their own .ini files but NOT have to modify/alter any lib. code. Makes for easy debugging, if the LIB. code is unchanged. 2/ If there is any updates/ revisions of the LIB code, no user has to remember all the mods/changes to their own versions. James, BTW Multi LCD Modules are actually easy to setup I agree,leave LCD.Bas "As IS" with maybe better documentation of changes needed for DM/MM Hardware and users needs. The LCD_Driver LIBRARY then needs to be developed as MODULAR "drop-in" code with NO internal changes/edits needed to be used by all end-users. Please to protect my sanity and that of others, NO HARD WIRED/Self edited Constants. Programming Languages have Data files and Subroutines have Parameters for exactly that reason. At bare minimum use DATA declarations VK4MU MicroController Units |
||||
James_From_Canb Senior Member Joined: 19/06/2011 Location: AustraliaPosts: 265 |
Hmmm. Looks like I can't PM a file to potential members of an LCD Working Party. I'll have to post it here for everyone to see. 2012-02-05_051119_lcd_lib.zip -------------------------------------------------- Here's a rough start to LCD_LIB.BAS. It will have routines for all the standard LCD functions defined in the H44780 spec sheet. It has Geoff's original routines and some custom ones to show how the standard ones can be called. It's completely untested. Much is still 'under development' - particularly the code to read data from the LCD. I'm posting it as 'an example of code' so we can work out some standards, not so people can identify bugs or typos. OK? As I see it, there would need to be at least 3 files: - Initialisation code to go at the start of the user's code (may include .ini) - Library code, consisting of subs only, to be inserted anywhere in the user's code - Demo code, with well documented examples of using the library. If the final version of the attached file was split into 3, would it meet the user needs? We need some form of naming convention for the files, but will be limited by the 8 characters allowed. We need some form of naming convention for subs in libraries. Otherwise the subs might end up with the same names as subs written by the user. Anything else we need to consider for libraries? Comments welcome. James My mind is aglow with whirling, transient nodes of thought careening through a cosmic vapor of invention. Hedley Lamarr, Blazing Saddles (1974) |
||||
djuqa Guru Joined: 23/11/2011 Location: AustraliaPosts: 447 |
Sounds good James, with just one comment Init Code should be part of the library subroutine and just called from the beginning of user code. VK4MU MicroController Units |
||||
James_From_Canb Senior Member Joined: 19/06/2011 Location: AustraliaPosts: 265 |
How about we interpret that as: The code to do the initialisation must be in the library, and driven by user supplied parameters (which might be loaded from an .ini file). The user must supply the parameters and call the initialisation code before any library subs are used, preferably at the beginning of the user code. Any change to a value used by the library must be performed by a sub in the library. That way the user never has to change (or even see) the library code, and the user only has to make changes to one area of code. James My mind is aglow with whirling, transient nodes of thought careening through a cosmic vapor of invention. Hedley Lamarr, Blazing Saddles (1974) |
||||
djuqa Guru Joined: 23/11/2011 Location: AustraliaPosts: 447 |
Exactly!. The subroutine and dacumentation should be Comprehesive and flexible enough to allow usage without no-one even needing to know the internal workings. VK4MU MicroController Units |
||||
centrex Guru Joined: 13/11/2011 Location: AustraliaPosts: 320 |
Hi to the clever ones. Has anyone thought about writing a Sub useing something similar to the SEROUT command as used in the Picaxe (serout 7,T2400,("?y3?x12finished") to drive lcd displays using one I/O pin. The display boards use a dedicated micro to drive any sort of LCD display, the 7 is the I/O pin T2400 is True2400 baud, ?y3 is the lcd row, ?x12 is the position then the text or a variable, all these parameters are user defined. The boards I am talking about come Prof Anderson and Wulfden Most of these boards run at 2400 baud although some can run at 9600. Makes for a simple compact easy to use method of driving an lcd. regards Cliff Cliff |
||||
Ray B Senior Member Joined: 16/02/2007 Location: AustraliaPosts: 219 |
I've previously used Anderson's serial to LCD preprogrammed chip with picaxe but that is a bit dated these days try this link for a $8.45 board that does the same and more. http://www.toysdownunder.com/serial-lcd-adapter.html . I've purchased a couple of these & they tested out OK with a picaxe. Yes the shortage of output pins is still a problem with the MM but if your application has the required 6 pins available then it is a cheaper overall solution. RayB from Perth WA |
||||
djuqa Guru Joined: 23/11/2011 Location: AustraliaPosts: 447 |
With at least 12 usable IO pins and mega-cheap 4/8 bit interfaced lcd modules from $4USD, the need for serial interfaced displays due to lack of IO pins has diminished somewhat. If needing any serial/i2c connected lcd Modules These are $14 USD complete with 16x2 lcd Display Arduino IIC/I2C/TWI 1602 Serial LCD Module Display VK4MU MicroController Units |
||||
centrex Guru Joined: 13/11/2011 Location: AustraliaPosts: 320 |
Not a problem with i/o pins it is just the simplicity of the serout command. I have tried the Toys downunder device on a Picaxe no problem but getting it to work on the MM is a totally different kettle of fish. I need someone to point me in the right direction using the serial output of the MM. regards Cliff Cliff |
||||
James_From_Canb Senior Member Joined: 19/06/2011 Location: AustraliaPosts: 265 |
there will be a slight delay on lcd- lib.bas. I'm back in hospital for a week or so, and an iPad is a terrible development device James My mind is aglow with whirling, transient nodes of thought careening through a cosmic vapor of invention. Hedley Lamarr, Blazing Saddles (1974) |
||||
James_From_Canb Senior Member Joined: 19/06/2011 Location: AustraliaPosts: 265 |
Someone has pointed out that the demo program LCD.BAS supplied in the user library doesn't work with the DM because of pin incompatibilities. It's trivial to write a DM version, or modify the original, but I need to know which pins to use. Any suggestions on which 4 consecutive DM pins to use for data, and which 2 DM pins to use for RS and EN? Reasons? This is likely to become a standard for DM LCD connection so it's better to identify possible problems now rather than later. I'll post this on the DM forum too. James My mind is aglow with whirling, transient nodes of thought careening through a cosmic vapor of invention. Hedley Lamarr, Blazing Saddles (1974) |
||||
James_From_Canb Senior Member Joined: 19/06/2011 Location: AustraliaPosts: 265 |
Here's the LCD_LIB.BAS so far. It implements all of the functions except the 8 bit interface, reading the status and address, and the CGRAM addressing. I've written code for these three functions, but haven't tested them. There's also a test program called LCD_Test.BAS. It's used to test each of the functions in the library. The library file has a LOT of comments, so programs that use it may run out of memory (until Geoff implements firmware with improved memory management). I wrote DE-REM.BAS, a simple program to strip out comments and reduce the size of a library. I've hard-coded the file names for simplicity. The output is a smaller file called LCD.LIB. DE-REM only has to be run if the library is modified. Load LCD_Test.BAS on the Maximite them merge in LCD.LIB. Save the result as LCD.BAS. You can then run the program. >Load "LCD_Test.BAS" or any program that will use the library. >Merge "LCD.LIB" >Save "LCD.BAS" or an appropriate name. Test_LCD.BAS has a sub called TestSubs. I've commented out all but one of the calls to test functions in that sub. If they tested OK on a 20x4 LCD I added an OK remark. Pick a function you're interested in and uncomment the test. If you have the time, uncomment more. While you have the file open, look for the line InitLCDSize(20,4). This sets the number of characters per line and the number of lines. If you have a different size LCD put the appropriate numbers in. I've put in code that I hope will support the DuinoMite. Maybe Djuka or another DM owner could test it. There's only one bug that I'm aware of. The first test in TestLCDFunctionSet displays a set of inverse squares instead of a message. It could take a while to track down, so I figured I'd release the library with a warning that TestLCDFunctionSet could have issues. Most users of the library will not be affected because Geoff's initialisation code is sufficient to display the message, and it would be unusual to call any of the LCDFunctionSet functions after initialisation. To use the library with your own code, cut and paste the top section of Test_LCD to the top of your code. Insert your stuff, then merge in LCD.LIB. Here's the zip file. 2012-03-10_163333_LCD.zip. It also contains the HD44780 spec sheet that I was working from, so if you can't understand my comments in the library you can go to the source. Regards James My mind is aglow with whirling, transient nodes of thought careening through a cosmic vapor of invention. Hedley Lamarr, Blazing Saddles (1974) |
||||
djuqa Guru Joined: 23/11/2011 Location: AustraliaPosts: 447 |
tested on duinomite mega/regular/mini with 16x2,8x2 +20x4 displays works ok only addition needed read the values of the module character size/lines/data/control pins/pin settings from a small text file "LCD.cfg" that way nothing needs to be edited in main program the bug has something to do with rwenabled status If you comment out the line [code]if rwenabled then setpin RW,2 [/code] it works perfectly VK4MU MicroController Units |
||||
Page 1 of 2 |
Print this page |