Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 09:42 26 Nov 2024 Privacy Policy
Jump to

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: Australia
Posts: 219
Posted: 02:42pm 30 Jan 2012
Copy link to clipboard 
Print this post

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: Australia
Posts: 219
Posted: 01:59am 31 Jan 2012
Copy link to clipboard 
Print this post

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: Australia
Posts: 265
Posted: 09:11pm 02 Feb 2012
Copy link to clipboard 
Print this post

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: Australia
Posts: 219
Posted: 01:42am 03 Feb 2012
Copy link to clipboard 
Print this post

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: Australia
Posts: 447
Posted: 03:05am 03 Feb 2012
Copy link to clipboard 
Print this post

  Ray B said   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



Cheers
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,
Edited by djuqa 2012-02-04
VK4MU MicroController Units

 
Ray B
Senior Member

Joined: 16/02/2007
Location: Australia
Posts: 219
Posted: 07:05am 03 Feb 2012
Copy link to clipboard 
Print this post

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: Australia
Posts: 265
Posted: 07:13am 03 Feb 2012
Copy link to clipboard 
Print this post

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: Australia
Posts: 447
Posted: 07:13am 03 Feb 2012
Copy link to clipboard 
Print this post

  Ray B said   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.
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

Edited by djuqa 2012-02-04
VK4MU MicroController Units

 
James_From_Canb

Senior Member

Joined: 19/06/2011
Location: Australia
Posts: 265
Posted: 07:46pm 04 Feb 2012
Copy link to clipboard 
Print this post

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: Australia
Posts: 447
Posted: 10:43pm 04 Feb 2012
Copy link to clipboard 
Print this post

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: Australia
Posts: 265
Posted: 01:09am 05 Feb 2012
Copy link to clipboard 
Print this post

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: Australia
Posts: 447
Posted: 01:12am 05 Feb 2012
Copy link to clipboard 
Print this post

  James_From_Canb said   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

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: Australia
Posts: 320
Posted: 08:25am 06 Feb 2012
Copy link to clipboard 
Print this post

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
CliffEdited by centrex 2012-02-07
Cliff
 
Ray B
Senior Member

Joined: 16/02/2007
Location: Australia
Posts: 219
Posted: 09:06am 06 Feb 2012
Copy link to clipboard 
Print this post

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: Australia
Posts: 447
Posted: 10:12am 06 Feb 2012
Copy link to clipboard 
Print this post

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

Edited by djuqa 2012-02-07
VK4MU MicroController Units

 
centrex

Guru

Joined: 13/11/2011
Location: Australia
Posts: 320
Posted: 07:40am 07 Feb 2012
Copy link to clipboard 
Print this post

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: Australia
Posts: 265
Posted: 06:34pm 07 Feb 2012
Copy link to clipboard 
Print this post

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: Australia
Posts: 265
Posted: 12:56am 27 Feb 2012
Copy link to clipboard 
Print this post

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: Australia
Posts: 265
Posted: 06:45am 10 Mar 2012
Copy link to clipboard 
Print this post

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: Australia
Posts: 447
Posted: 07:47am 10 Mar 2012
Copy link to clipboard 
Print this post

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 perfectlyEdited by djuqa 2012-03-11
VK4MU MicroController Units

 
     Page 1 of 2    
Print this page
© JAQ Software 2024