Steve, very good result !
I think It will help a lot of people too .
I am wait to receive the item ( about 20 days ).
Could you please post the code : I will start to study it .
Thanks
Ambrogio
Steve, very good result !
I think It will help a lot of people too .
I am wait to receive the item ( about 20 days ).
Could you please post the code : I will start to study it .
Thanks
Ambrogio
Here it is. This is a simple test program for PBP2.5 or lower. Anything you do not understand please ask. The next step is to include the command selection inside the LCD_WRITE subroutine.
Code:'**************************************************************** '* Name : I2CLCD.BAS '* Author : Steve Earl '* Notice : Copyright (c) 2014 [select VIEW...EDITOR OPTIONS] '* : All Rights Reserved '* Date : 17/07/2014 '* Version : 1.0 '* Notes : Serial I2C LCD using PBP 2.5 '* : PCF8574T I2C port expander 20x4 LCD '**************************************************************** define OSC 40 ' set the correct speed here!! 'DEFINE I2C_SLOW 1 SDA VAR PORTD.2 ; I2C Data pin SCL VAR PORTD.3 ; I2C Clock Pin LCD_Addr CON 78 ; PCF8574T address 'LCD_BuffSize CON 30 'LCD_Buff VAR BYTE[LCD_BuffSize] 'LCD_BuffAddr CON EXT : @LCD_BuffAddr = _LCD_Buff 'LCD_BuffLen VAR WORD ; Length of data in buffer LCD_Data VAR BYTE ; Data to Send to LCD LCD_Byte VAR BYTE ; Nibbles to Send LCD_RS VAR LCD_Byte.0 ; Register Select bit LCD_RW VAR LCD_Byte.1 ; Read/Write bit LCD_E VAR LCD_Byte.2 ; Enable bit LCD_BackLight VAR LCD_Byte.3 ; Backlight 1=ON LCD_WriteMode VAR BYTE ; 1=LowNibble, 2=HighNibble, 3=Both 'LCD_CommandMode VAR BIT ; Indicates next byte is a command LCD_Byte2 VAR BYTE ; Same nibble without E bit 'LCD_Idx VAR BYTE seconds var byte minutes var byte hours var byte Init: ;----[Initialize the LCD]------------------------------------------------------- PAUSE 250 ; LCD Power-on delay LCD_Backlight = 1 ; Backlight On LCD_RW = 0 ; Write to LCD LCD_RS = 0 ; Command Register LCD_WriteMode = 1 ;-- Low Nibbles only LCD_Data = 3 ; Software Reset 3 times gosub LCD_Write : PAUSEUS 6000 gosub LCD_Write : PAUSEUS 1000 gosub LCD_Write : PAUSEUS 1000 LCD_Data = 2 ; Start 4-bit mode gosub LCD_Write : PAUSEUS 1000 LCD_WriteMode = 3 ;-- Both Nibbles LCD_Data = $28 : gosub LCD_Write ; Function Set, 4-bit, 2-line, 5x7 LCD_Data = $0C : gosub LCD_Write ; Display ON LCD_Data = $01 : gosub LCD_Write ; Clear Screen PAUSE 50 LCD_Data = $06 : gosub LCD_Write ; Entry Mode PAUSE 2 ; Let command finish LCD_RS = 1 ;Switch to Data ;Print Static Background to LCD LCD_Data = " " : gosub LCD_Write ;Line 1 LCD_Data = " " : gosub LCD_Write LCD_Data = " " : gosub LCD_Write LCD_Data = " " : gosub LCD_Write LCD_Data = " " : gosub LCD_Write LCD_Data = "S" : gosub LCD_Write LCD_Data = "t" : gosub LCD_Write LCD_Data = "e" : gosub LCD_Write LCD_Data = "v" : gosub LCD_Write LCD_Data = "e" : gosub LCD_Write LCD_Data = " " : gosub LCD_Write LCD_Data = "E" : gosub LCD_Write LCD_Data = "a" : gosub LCD_Write LCD_Data = "r" : gosub LCD_Write LCD_Data = "l" : gosub LCD_Write lcd_rs = 0 ;Command is next lcd_data=$a8 : gosub lcd_write ;Move to start of line 2 pause 2 lcd_rs = 1 ;Switch back to Data LCD_Data = " " : gosub LCD_Write ;Line 2 LCD_Data = " " : gosub LCD_Write LCD_Data = "D" : gosub LCD_Write LCD_Data = "a" : gosub LCD_Write LCD_Data = "t" : gosub LCD_Write LCD_Data = "a" : gosub LCD_Write LCD_Data = "g" : gosub LCD_Write LCD_Data = "e" : gosub LCD_Write LCD_Data = "o" : gosub LCD_Write LCD_Data = " " : gosub LCD_Write LCD_Data = "L" : gosub LCD_Write LCD_Data = "i" : gosub LCD_Write LCD_Data = "m" : gosub LCD_Write LCD_Data = "i" : gosub LCD_Write LCD_Data = "t" : gosub LCD_Write LCD_Data = "e" : gosub LCD_Write LCD_Data = "d" : gosub LCD_Write lcd_rs = 0 ;Command is next lcd_data=$99 : gosub lcd_write ;Move to line 3 col 6 pause 2 lcd_rs = 1 ;Switch back to Data LCD_Data = "*" : gosub LCD_Write ;Line 3 LCD_Data = "*" : gosub LCD_Write LCD_Data = "*" : gosub LCD_Write LCD_Data = "*" : gosub LCD_Write LCD_Data = "*" : gosub LCD_Write LCD_Data = "*" : gosub LCD_Write LCD_Data = "*" : gosub LCD_Write LCD_Data = "*" : gosub LCD_Write LCD_Data = "*" : gosub LCD_Write LCD_Data = "*" : gosub LCD_Write lcd_rs = 0 ;Command is next lcd_data=$D8 : gosub lcd_write ;Move to line 4 col 5 pause 2 lcd_rs = 1 ;Switch back to Data LCD_Data = "T" : gosub LCD_Write ;Line 4 LCD_Data = "e" : gosub LCD_Write LCD_Data = "s" : gosub LCD_Write LCD_Data = "t" : gosub LCD_Write LCD_Data = " " : gosub LCD_Write LCD_Data = "P" : gosub LCD_Write LCD_Data = "r" : gosub LCD_Write LCD_Data = "o" : gosub LCD_Write LCD_Data = "g" : gosub LCD_Write LCD_Data = "r" : gosub LCD_Write LCD_Data = "a" : gosub LCD_Write LCD_Data = "m" : gosub LCD_Write pause 5000 lcd_rs = 0 ;Command is next lcd_data=$D8 : gosub lcd_write ;Move to line 4 col 5 pause 2 lcd_rs = 1 ;Switch back to Data LCD_Data = " " : gosub LCD_Write ;Clear line 4 and set clock LCD_Data = " " : gosub LCD_Write LCD_Data = "0" : gosub LCD_Write LCD_Data = "0" : gosub LCD_Write LCD_Data = ":" : gosub LCD_Write LCD_Data = "0" : gosub LCD_Write LCD_Data = "0" : gosub LCD_Write LCD_Data = ":" : gosub LCD_Write LCD_Data = "0" : gosub LCD_Write LCD_Data = "0" : gosub LCD_Write LCD_Data = " " : gosub LCD_Write LCD_Data = " " : gosub LCD_Write main: ;Count seconds and refresh the clock for hours = 0 to 23 for minutes = 0 to 59 for seconds = 0 to 59 lcd_rs = 0 ;Command is next lcd_data=$DA : gosub lcd_write ;Move to line 4 col 7 pause 2 lcd_rs = 1 ;Switch back to Data LCD_Data = (hours dig 1)+48 : gosub LCD_Write LCD_Data = (hours dig 0)+48 : gosub LCD_Write LCD_Data = ":" : gosub LCD_Write LCD_Data = (minutes dig 1)+48 : gosub LCD_Write LCD_Data = (minutes dig 0)+48 : gosub LCD_Write LCD_Data = ":" : gosub LCD_Write LCD_Data = (seconds dig 1)+48 : gosub LCD_Write LCD_Data = (seconds dig 0)+48 : gosub LCD_Write pause 1000 next ;second next ;minute next ;hour goto main LCD_WRITE: LCD_E = 1 IF LCD_WriteMode.1 = 1 THEN ; Write High Nibble LCD_Byte = (LCD_Byte & $0F) | (LCD_Data & $F0) LCD_Byte2 = LCD_Byte & $FB I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2] ENDIF IF LCD_WriteMode.0 = 1 THEN ; Write Low Nibble LCD_Byte = (LCD_Byte & $0F) | ((LCD_Data << 4 )& $F0) LCD_Byte2 = LCD_Byte & $FB I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2] ENDIF return
Steve Earl www.datageo.co.uk
Ambrogio,
Any feedback?
If you have no questions then I will post the next improvement which includes the command in the LCD_Write subroutine. I am now looking at using arrays as the next step.
Steve Earl www.datageo.co.uk
Here it is! including LOOKUP and ARRAYs.
Code:'**************************************************************** '* Name : I2CLCD.BAS * '* Author : Steve Earl * '* Notice : Copyright (c) 2014 [select VIEW...EDITOR OPTIONS] * '* : All Rights Reserved * '* Date : 17/07/2014 * '* Version : 1.0 * '* Notes : Serial I2C LCD using PBP 2.5 * '* : PCF8574T I2C port expander 20x4 LCD * '**************************************************************** define OSC 40 ' set the correct speed here!! 'DEFINE I2C_SLOW 1 SDA VAR PORTD.2 ; I2C Data pin SCL VAR PORTD.3 ; I2C Clock Pin LCD_Addr CON 78 ; PCF8574T address LCD_Line_1 con $80 LCD_Line_2 con $A8 LCD_Line_3 con $94 LCD_Line_4 con $D4 LCD_BuffSize CON 22 LCD_Buff VAR BYTE[LCD_BuffSize] 'LCD_BuffAddr CON EXT : @LCD_BuffAddr = _LCD_Buff LCD_BuffLen VAR byte ; Length of data in buffer LCD_Data VAR BYTE ; Data to Send to LCD LCD_Byte VAR BYTE ; Nibbles to Send LCD_RS VAR LCD_Byte.0 ; Register Select bit LCD_RW VAR LCD_Byte.1 ; Read/Write bit LCD_E VAR LCD_Byte.2 ; Enable bit LCD_BackLight VAR LCD_Byte.3 ; Backlight 1=ON LCD_WriteMode VAR BYTE ; 1=LowNibble, 2=HighNibble, 3=Both LCD_CommandMode VAR BIT ; Indicates next byte is a command LCD_Byte2 VAR BYTE ; Same nibble without E bit LCD_Idx VAR BYTE seconds var byte minutes var byte hours var byte Init: ;----[Initialize the LCD]------------------------------------------------------- PAUSE 250 ; LCD Power-on delay LCD_Backlight = 1 ; Backlight On LCD_RW = 0 ; Write to LCD LCD_RS = 0 ; Command Register LCD_WriteMode = 1 ;-- Low Nibbles only LCD_Data = 3 ; Software Reset 3 times gosub LCD_Write : PAUSEUS 6000 gosub LCD_Write : PAUSEUS 1000 gosub LCD_Write : PAUSEUS 1000 LCD_Data = 2 ; Start 4-bit mode gosub LCD_Write : PAUSEUS 1000 LCD_WriteMode = 3 ;-- Both Nibbles LCD_buff[0] = $28 ; Function Set, 4-bit, 2-line LCD_buff[1] = $0C ; Display ON LCD_buff[2] = $FE LCD_buff[3] = $06 ; Entry Mode LCD_buff[4] = $FE LCD_buff[5] = $01 ; Clear Screen lcd_bufflen = 6 gosub LCD_Buff_Write ;Print Static Background to LCD for lcd_idx = 0 to 85 ;| | 20 characters lookup lcd_idx,[" Steve Earl ",_ ;20 $FE,lcd_line_2," Datageo Limited ",_ ;+22 = 42 $FE,lcd_line_3," ********** ",_ ;+22 = 64 $FE,lcd_line_4," 00:00:00 "],lcd_data ;+22 = 86 (0-85) gosub lcd_write next ;Set up fixed buffer characters lcd_bufflen = 10 ;8 characters in clock + $FE + LCD_Line LCD_buff[0] = $FE ;Command is next LCD_buff[1] = lcd_line_4 + 6 ;Move to line 4 col 7 LCD_buff[4] = ":" ;Fixed characters LCD_buff[7] = ":" ; " main: ;Count seconds and refresh the clock for hours = 0 to 23 for minutes = 0 to 59 for seconds = 0 to 59 LCD_buff[2] = (hours dig 1)+48 LCD_buff[3] = (hours dig 0)+48 LCD_buff[5] = (minutes dig 1)+48 LCD_buff[6] = (minutes dig 0)+48 LCD_buff[8] = (seconds dig 1)+48 LCD_buff[9]= (seconds dig 0)+48 gosub lcd_buff_write pause 1000 next ;second next ;minute next ;hour goto main LCD_WRITE: if lcd_data = $FE then lcd_commandMode = 1 ;Next byte Command lcd_rs = 0 ;Switch to Command Register else LCD_E = 1 IF LCD_WriteMode.1 = 1 THEN ; Write High Nibble LCD_Byte = (LCD_Byte & $0F) | (LCD_Data & $F0) LCD_Byte2 = LCD_Byte & $FB I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2] ENDIF IF LCD_WriteMode.0 = 1 THEN ; Write Low Nibble LCD_Byte = (LCD_Byte & $0F) | ((LCD_Data << 4 )& $F0) LCD_Byte2 = LCD_Byte & $FB I2CWRITE SDA,SCL, LCD_Addr,[LCD_Byte, LCD_Byte2] ENDIF if lcd_commandmode then lcd_commandmode = 0 ;Reset to data lcd_rs = 1 ;Switch to Data Register pause 2 endif endif return Lcd_Buff_Write: for lcd_idx = 0 to lcd_bufflen - 1 lcd_data=lcd_buff[LCD_idx] gosub LCD_Write next return
Steve Earl www.datageo.co.uk
Steve,
I am sorry for the delayed reply : I am not at home on those days.
I had a look to your code : it is a good work and I am waiting to check it soon when the hardware is arrived .
Thanks a lot for the assistance.
I think your work will help a lot of people .
Regards,
Ambrogio
I tried using the on board EEPROM by using DATA and READ.
DATA "This is a string",0
but it stores only alternate characters. I was surprised it worked at all but the alternate characters? There has to be a reason for it to work this way.
Steve Earl www.datageo.co.uk
It looks like this was fixed back in 2010.
http://www.picbasic.co.uk/forum/showthread.php?t=12775
My PBP2.46 is from 2005.
Steve Earl www.datageo.co.uk
The plot thickens! Here is an extract from this thread http://www.picbasic.co.uk/forum/show...7143#post97143 using DATA with strings and it works.
Steve Earl www.datageo.co.uk
Ambrogio
After more testing of the DATA command I have come to the conclusion that my very old setup is the cause. I have PBP2.46 and MCSP from ten years ago. Looking at my old code, ten years old, I used WRITE not DATA and I now believe that was because DATA never worked. I wrote a routine just to write to the EEPROM followed by the program fortunately my set up did not overwrite the EEPROM when the PIC was reprogramed, Bruce's FlashLab boards continue to perform flawlessly.
There are three options for the screen setup
1 LOOKUP
2 Embedded string
3 EEPROM
They all work but LOOKUP uses most code space and EEPROM the least.
Steve Earl www.datageo.co.uk
Steve,
I am very interested in test the programs but I am still waiting to receive the PCF expander.
It will arrive here after my summer holidays. I will let you know.
Thanks for all.
Regards,
Ambrogio
Ciao Ambrogio,
take a look here ... could help!
http://www.protonbasic.co.uk/showthr...ck-on-1602-LCD
Leo
Leo
Thanks to all of you in this forum for the assistance.
I am having problem with my healt in this last period of time. I had an important surgery.
I hope to be active again.
Ambrogio
IW2FVO
Bookmarks