PDA

View Full Version : Replacing LCDOUT with direct statements?



CuriousOne
- 5th February 2022, 09:44
Hello.
After I got external EEPROM working, now it's time to do some graphics.
For this purpose I use ST7920 controller based LCD, which has parallel interface, so works directly with LCDOUT statement, making many complicated things simpler. However, it can't transmit $FE to display, since it is used as statement. This creates many issues with graphics to be sent to display. So I have to replace LCDOUT with something "discrete".
I've read HD44780 manual, but some moments are not clear, so are there any code ideas, with which I just can simply send required byte to HD44780 compatible screen, in 4 bit mode, but without using LCDOUT statement?

Ioannis
- 5th February 2022, 11:57
When I was young I did that on a Z80 self made computer in assembly.

Surely I will not do it again... Too much work.

I do understand why you want this. Too cheap as graphic display but too much complicated to make it work with Lcdout. Better use a Nextion display. Easier, many colors, RS232 controled and touch input too!

Ioannis

HenrikOlsson
- 5th February 2022, 15:17
I've read HD44780 manual, but some moments are not clear, so are there any code ideas, with which I just can simply send required byte to HD44780 compatible screen, in 4 bit mode, but without using LCDOUT statement?
Since LCDOUT works perfectly fine for the HD44780 for which it is meant there's probably never been a need to sort of recreate the same functionallity. Obviously loads and loads of examples for assembly, both PIC and other uC can be found on the internet but you're not interested in that.

What "moments" are not clear specifically? Perhaps we can clear those "moments" up and then you'll be fine.

Are you intending to completely replace LCDOUT or are you trying to find a solution only for the occation(s) when you need to send 254?

CuriousOne
- 5th February 2022, 15:46
Regarding the nextion display, unfortunately, while in general, idea is good, there are several key disadvantages:
1. High cost
2. Bad quality, low contrast, bad viewing angle and not sunlight readable display.
3. Need for SD card
4. Long boot time
5. Complicated, badly written and not user oriented IDE

So nextion is junk, and unless they fixed all these 5 (which is not going to happen anyways), I'm not going to look for it :)

Contrary to that, ST7920 display is pin to pin compatible with standard 1602 LCD modules, has actually two display framebuffers - one for HD44780 mode, another for graphical, and it does OR for them automatically - so you can write text via HD44780 mode, and use graphic mode to only display graphical elements, their overlay is automatically handled by display - thus removing requirement for large amount of ram, rom, eeprom and need to keep separate framebuffer.



As I understand, working with HD44780 means manipulation with Enable and RS pins, and setting data pins according to required bytes to be sent, and spitting them into two 4 bit parts. So since I usually connect 44780 pins to single port in sequence - like data lines to portb.0-portb.3 and RS and E pins to PORTB.4 and PORTB.5, I guess there should be a statement, which allows to set port bits according to certain variable bits. So after reading HD44780 manual, I don't think it will be too complicated to do bitbanging and drive it in that way...

HenrikOlsson
- 5th February 2022, 16:24
I've actually used a Nextion displays for a project or two because that's what the customer wanted and I must say find a couple of your comments a bit strange. In fact it makes me wonder if YOU have actually tried one....

1. High cost <-OK, relative to a 1602 or 128x64 graphics display, sure. But compared to a similar product from say 4D Systems, no.
2. Bad quality, low contrast, bad viewing angle and not sunlight readable display. <- Only used in indoors so can't comment on that
3. Need for SD card <- Certainly not. None of the projects I've done with them have use an SD card.
4. Long boot time <- What? Please define long. In my experience they start like "instantly".
5. Complicated, badly written and not user oriented IDE <- Sure, it's a bot rough but it does get the job done and it allows you test out commands etc virtually.

EDIT, I just dug one of mine out and powered it up.
Yes, it starts "instantly" (less than 1s). No, there's no SD-card in it and it still works.
Black text on white background is no problem reading at almost ANY angle but black text on gray buttons does wash out when viewed from the 6 o'clock position.

Ioannis
- 5th February 2022, 16:37
Regarding the nextion display, unfortunately, while in general, idea is good, there are several key disadvantages:
1. High cost
2. Bad quality, low contrast, bad viewing angle and not sunlight readable display.
3. Need for SD card
4. Long boot time
5. Complicated, badly written and not user oriented IDE


1. comparing to a 12864 monochrome LCD, at about the same size i think it is about 25 euros. So for a color full graphics no. It is not.
2. My iPhone is also not readable under the sun. Other than that, I found them very acceptable for the price.
3. No need for SD. The SD is only for loading the program. But that can be done with RS232 also. Not true then.
4. Boot is instant. Maybe faster than the PIC that it will communicate!
5. The IDE is different than MCStudio. But not bad! Instead it is helpful and also has emulator that can be used with the PCs RS232 and communicate with your PIC so you can test the system even before you purchase the LCD itself!

You may need to test it and see for yourself.

I have a 12864 display but never managed to control it from a PIC. Maybe it is time to show how. The one I got is WG12864D by Winstar with T6963C controller and a couple of LC7940 chips.

Ioannis

Ioannis
- 5th February 2022, 17:41
Have you seen this: http://www.picbasic.co.uk/forum/showthread.php?t=19842

Also this but for a different controller: http://www.compsys1.com/support/PBP_Files/glipic/glipicw.bas

Ioannis

CuriousOne
- 5th February 2022, 17:45
1. ST7920 module has same physical dimensions and outline as standard 1602 LCD module, but has 132x32 pixels resolution and larger physical area of pixels (less wasted space, compared to traditional 1602 displays). This means that it can display up to 18 characters x 4 lines using standard 8x8 font matrix. You can have a look here (The slow drawing is animation effect, using LCDOUT it is possible to update whole screen at approximately 20fps rate): https://www.youtube.com/watch?v=zIQsg1fv2V0

Regarding the 25 euros, I don't know where you buy them, but I bought nextion on taobao, the basic model, for about $11. ST7920 LCD module is about $6, standard 1602 LCD module is about $1. OLED 1602 - also $10.

2. Your iphone, your issues. I like my devices to be fully accessible and have as few disabilities, as possible.

3. And where store graphics, sound files, etc, without SD ?

4. I don't see any instant boot times, with empty code - maybe.

5. I have tried it by myself, several times, several versions. IDE looks like monkey's drawing - visually they tried to emulate visual studio, but they didn't went into internals.

mpgmike
- 5th February 2022, 18:18
I did a project several years ago for a friend. Maybe this code can help you. This isn't the entire program, but close. I am updating only values that change, leaving the rest alone.



'* Date : 8/13/2017 *
'* Version : 1.6 *
'* Notes : PIC18F26K22 *


RS var PORTC.6 ;Register Select for LCD, 0 = Comd, 1 = Data
En var PORTC.7 ;Pulsout Enable to write to LCD


b0 var byte ;Main For/Next Loop Variable
b1 var byte ;LCDout Variable
b3 var byte ;For/Next Loop Variable
BatL var byte ;Display Screen Position Number
Batt var byte ;Battery Voltage, ADC Steps
BattA var byte[3] ;Battery Voltage, ASCii Converted
BatV var byte ;Battery Voltage XX(.)X
CFG var byte ;Set-Up Bits, DATA @10
Disp_Sel var byte ;Cursor Points To, 10 Choices in Disp_Prog
DispSet var CFG.3 ;Denotes Display Programming Complete
IOL var byte ;Display Screen Position Number
Line1 var byte[17] ;Disp_Prog Line1 Display Data Variable
Line2 var byte[17] ;Disp_Prog Line2 Display Data Variable
Line3 var byte[17] ;Disp_Prog Line3 Display Data Variable
Line4 var byte[17] ;Disp_Prog Line4 Display Data Variable
LnSel var byte ;Line Selected, 1 >> 4d
LPsi var byte ;Low Operating Pressure
LPsiA var byte[2] ;LPsi ASCii Converted
Order var byte ;Used in Disp: for positioning
OrderCt var byte ;Disp_Prog Order Keeper for Variables Displayed, Line1
Pos var byte ;Display Screen Position Number
Psi1 var byte ;Vaporizer Pressure, ADC Steps (8 bit)
Psi1A var byte[2] ;Vaporizer Pressure, ASCii Converted
Psi1L var byte ;Display Screen Position Number
Psi1P var byte ;Vaporizer Pressure, ADC >> Psi
Psi2 var byte ;Regulated Pressure, ADC Steps (8 bit)
Psi2A var byte[2] ;Regulated Pressure, ASCii Converted
Psi2L var byte ;Display Screen Position Number
Psi2P var byte ;Regulated Pressure, ADC >> Psi
PTarg var byte ;Target Vaporizer Pressure, Psi
PTargA var byte[2] ;Target Vaporizer Pressure, ASCii Converted
PTargL var byte ;Display Screen Position Number
Ppres var byte ;Target Vaporizer Pressure, ADC >> Psi
TPS var byte ;TPS ADC Steps, Read/Display Only
TPSA var byte[3] ;TPS Volts, ASCii Converted
TPSL var byte ;Display Screen Position Number
TPSV var word ;TPS Volts, 0.00 >> 5.00
VDCL var byte ;Display Screen Position Number
VTL var byte ;Display Screen Position Number
Work var byte ;Source of Working Bits


;Program Labels:


Init:
Order = 0 ;Display top of screen
Work = 0 ;Stock, Clears All Operating Bits
LnSel = 1 ;Line Selected for Display
Source = 1 ;Stock on Output to CNG ECU
GP = 0
Inj = 0
Rled = 0
pause 100
gosub Load_Vars ;Loads EEPROM Values into Appropriate Variables
goto Init_LCD ;Starts LCD, Loads Start Screens


Main:
;do stuff
gosub Disp
goto Main




Init_LCD:
low RS
PORTB = $30
high En
pauseus 4
low En
pause 5
PORTB = $30
high En
pauseus 4
low En
pauseus 160
PORTB = $30
high En
pauseus 4
low En
pauseus 160
PORTB = $38
gosub Send
PORTB = $10
gosub Send
PORTB = $0C
gosub Send
PORTB = $06
gosub Send
PORTB = 1
gosub Send
pause 1
PORTB = $80
gosub Send
high RS
pause 1
for b0 = 0 to 15
lookup b0, [" T-Cat Fuel Sys "], b1
PORTB = b1
gosub Send
next b0
low RS
pause 1
PORTB = $C0
gosub Send
high RS
pause 1
for b0 = 0 to 15
lookup b0, [" Controller "], b1
PORTB = b1
gosub Send
next b0
low RS
pause 1
PORTB = $90
gosub Send
high RS
pause 1
for b0 = 0 to 15
lookup b0, [" R & D Club "], b1
PORTB = b1
gosub Send
next b0
low RS
pause 1
PORTB = $D0
gosub Send
high RS
pause 1
for b0 = 0 to 15
lookup b0, [" Version 1.7 "], b1
PORTB = b1
gosub Send
next b0
pause 500
for b0 = 1 to 5
pause 250
Rled = 1
pause 250
Rled = 0
next b0
Start_Screen:
low RS
PORTB = 1
gosub Send
PORTB = $80 ;Line 1
gosub Send
high RS
pause 1
for b0 = 0 to 15
lookup b0, [" To Switch, 1/0 "], b1
PORTB = b1
gosub Send
next b0
pause 1
low RS
PORTB = $C0 ;Line 2
gosub Send
high RS
pause 1
for b0 = 0 to 15
lookup b0, [" Display Val ^ "], b1
PORTB = b1
gosub Send
next b0
pause 1
low RS
PORTB = $90 ;Line 3
gosub Send
high RS
pause 1
for b0 = 0 to 15
lookup b0, [" Program ^ & v "], b1
PORTB = b1
gosub Send
next b0
low RS
PORTB = $D0
gosub Send
high RS
pause 1
for b0 = 0 to 15
lookup b0, ["T-Cat Controller"], b1
PORTB = b1
gosub Send
next b0
Start2:
Source = 1
do
loop while (ButU = 0) and (ButT = 0) and (ButD = 0) and (Sw = 0)
if Sw = 1 then
pause 50
if Sw = 1 then
IO = 1
do
loop while SW = 1
; Source = 0
GP = 0
Inj = 0
Rled = 0
PAUSE 200
goto Main
endif
endif
If (ButU = 1) or (ButD = 1) then
pause 50
if (ButU = 1) and (ButD = 0) then
do
loop while ButU = 1
GP = 0
Inj = 0
Rled = 0
PAUSE 200
goto Park
endif
if (ButU = 1) and (ButD = 1) then
do
loop while (ButU = 1) and (ButD = 1)
goto Prog0
endif
endif
goto Start2


Disp:
LnSel = 1
low RS
PORTB = 1
gosub Send
PORTB = $80
gosub Send
high RS
OrderCt = LnSel + Order
gosub Disp_Seq
LnSel = LnSel + 1
low RS
PORTB = $C0
gosub Send
high RS
OrderCt = LnSel + Order
gosub Disp_Seq
LnSel = LnSel + 1
low RS
PORTB = $90
gosub Send
high RS
OrderCt = LnSel + Order
gosub Disp_Seq
LnSel = LnSel + 1
low RS
PORTB = $D0
gosub Send
high RS
OrderCt = LnSel + Order
gosub Disp_Seq
LnSel = 1
return


Disp_Seq:
Select Case OrderCt
case is = 1 : gosub Set_TC1L ;Vap Temp
case is = 2 : gosub Set_PSI1L ;Vap PSI
case is = 3 : gosub Set_PSI2L ;Regulated PSI
case is = 4 : gosub Set_PTargL ;Vap PSI Targ
case is = 5 : gosub Set_LPsiL ;Low PSI Aux Enable
case is = 6 : gosub Set_TPSL ;TPS
case is = 7 : gosub Set_BatL ;Battery Volts
end Select
return


Set_LPsiL:
ARRAYWRITE LPsiA, [#LPsi]
for b0 = 0 to 13
LOOKUP b0,["Low PSI Set = "],b1
PORTB = b1
gosub Send
next b0
if LPsi < 10 then
LPsiA[1] = LPsiA[0]
LPsiA[0] = " "
endif
PORTB = LPsiA[0]
gosub Send
PORTB = LPsiA[1]
gosub Send
RETURN


Set_BatL:
ARRAYWRITE BATTA, [#BatV]
for b0 = 0 to 9
LOOKUP b0,["Battery = "],b1
PORTB = b1
gosub Send
next b0
if BatV < 100 then
BattA[2] = BattA[1]
BattA[1] = BattA[0]
BattA[0] = " "
endif
PORTB = BattA[0]
gosub Send
PORTB = BattA[1]
gosub Send
PORTB = "."
gosub Send
PORTB = BattA[2]
gosub Send
PORTB = " "
gosub Send
PORTB = "V"
gosub Send
return


Set_Psi1L:
ARRAYWRITE PSI1A, [#Psi1P]
for b0 = 0 to 9
LOOKUP b0,["Vap Psi = "],b1
PORTB = b1
gosub Send
next b0
if PSI1P < 10 then
PSI1A[1] = PSI1A[0]
PSI1A[0] = " "
endif
PORTB = PSI1A[0]
gosub Send
PORTB = PSI1A[1]
gosub Send
for b0 = 0 to 3
PORTB = " "
gosub Send
next b0
return


Set_Psi2L:
ARRAYWRITE Psi2A, [#Psi2P]
for b0 = 0 to 9
LOOKUP b0,["Reg Psi = "],b1
PORTB = b1
gosub Send
next b0
if PSI2P < 10 then
PSI2A[1] = PSI2A[0]
PSI2A[0] = " "
endif
PORTB = Psi2A[0]
gosub Send
PORTB = Psi2A[1]
gosub Send
for b0 = 0 to 3
PORTB = " "
gosub Send
next b0
return


Set_PTargL:
ARRAYWRITE PTargA, [#PTarg]
for b0 = 0 to 13
LOOKUP b0,["Vap PsiTarg = "],b1
PORTB = b1
gosub Send
next b0
PORTB = PTargA[0]
gosub Send
PORTB = PTargA[1]
gosub Send
return


Set_TC1L:
arraywrite TC1A, [#TC1F]
for b0 = 0 to 10
LOOKUP b0,["Vap Temp = "],b1
PORTB = b1
gosub Send
next b0
if TC1F < 100 then
TC1A[2] = TC1A[1]
TC1A[1] = TC1A[0]
TC1A[0] = " "
endif
PORTB = TC1A[0]
gosub Send
PORTB = TC1A[1]
gosub Send
PORTB = TC1A[2]
gosub Send
PORTB = " "
gosub Send
PORTB = " "
gosub Send
return


Set_TPSL:
ARRAYWRITE TPSA, [#TPSV]
for b0 = 0 to 5
LOOKUP b0,["TPS = "],b1
PORTB = b1
gosub Send
next b0
if TPSV < 100 then
TPSA[2] = TPSA[1]
TPSA[1] = TPSA[0]
TPSA[0] = "0"
endif
if TPSV < 10 then
TPSA[2] = TPSA[1]
TPSA[1] = "0"
TPSA[0] = "0"
endif
PORTB = TPSA[0]
gosub Send
PORTB = "."
gosub Send
PORTB = TPSA[1]
gosub Send
PORTB = TPSA[2]
gosub Send
for b0 = 0 to 5
LOOKUP b0,[" Volts"],b1
PORTB = b1
gosub Send
next b0
return


Send:
high En
pauseus 8
low En
pause 1
return


Line_Select:
select Case LnSel
case is = 1 : PORTB = $80
case is = 2 : PORTB = $C0
case is = 3 : PORTB = $90
case is = 4 : PORTB = $D0
end select
return


Prog0:
read 6,PTarg
Prog0d:
do
loop while (ButU = 1) or (ButD = 1) or (ButT = 1)
low RS
pause 1
PORTB = 1
gosub Send
PORTB = $80
gosub Send
pause 1
high RS
pause 1
for b0 = 0 to 15
LOOKUP b0,["Target Vap Pres "],b1
PORTB = b1
gosub Send
next b0
low RS
pause 1
PORTB = $C0
gosub Send
high RS
pause 1
for b0 = 0 to 3
LOOKUP b0,[" "],b1
PORTB = b1
gosub Send
next b0
arraywrite PTargA, [#PTarg]
if PTarg < 10 then
PTargA[1] = PTargA[0]
PTargA[0] = " "
endif
PORTB = PTargA[0]
gosub Send
PORTB = PTargA[1]
gosub Send
if ButU = 1 then
PTarg = PTarg + 1
goto Prog0d
elseif ButD = 1 then
PTarg = PTarg - 1
goto Prog0d
endif
for b0 = 0 to 3
LOOKUP b0,[" PSI"],b1
PORTB = b1
gosub Send
next b0
if ButU = 1 then
PTarg = PTarg + 1
pause 10
goto Prog0d
elseif ButD = 1 then
PTarg = PTarg - 1
pause 10
goto Prog0d
endif
do
loop while (ButU = 0) and (ButD = 0) and (ButT = 0)
if ButU = 1 then
pause 100
if (ButU = 1) and (ButD = 0) and (ButT = 0) then
PTarg = PTarg + 1
for b0 = 0 to 100
if ButU = 0 then
goto Prog0d
endif
pause 10
next b0
endif
endif
if ButD = 1 then
pause 100
if (ButD = 1) and (ButU = 0) and (ButT = 0) then
PTarg = PTarg - 1
for b0 = 0 to 100
if ButD = 0 then
goto Prog0d
endif
pause 10
next b0
endif
endif
if ButT = 1 then
pause 250
if ButT = 1 then
do
loop while ButT = 1
write 6,PTarg
goto Prog1
endif
endif
if (ButU = 1) or (ButD = 1) then
pause 250
if (ButU = 1) and (ButD = 1) then
goto Start_Screen
endif
endif
goto Prog0d

Prog1:
read 7,LPsi
Prog1d:
do
loop while (ButU = 1) or (ButD = 1) or (ButT = 1)
low RS
pause 1
PORTB = 1
gosub Send
PORTB = $80
gosub Send
high RS
pause 1
for b0 = 0 to 15
LOOKUP b0,[" Low Operating "],b1
PORTB = b1
gosub Send
next b0
low RS
pause 1
PORTB = $C0
gosub Send
high RS
pause 1
for b0 = 0 to 15
LOOKUP b0,[" Pressure = "],b1
PORTB = b1
gosub Send
next b0
low RS
pause 1
PORTB = $90
gosub Send
high RS
pause 1
arraywrite LPsiA, [#LPsi]
if LPsi < 10 then
LPsiA[1] = LPsiA[0]
LPsiA[0] = " "
endif
PORTB = LPsiA[0]
gosub Send
PORTB = LPsiA[1]
gosub Send
for b0 = 3 to 14
LOOKUP b0,[" PSI "],b1
PORTB = b1
gosub Send
next b0
if (ButU = 1) and (LPsi < 40) then
LPsi = LPsi + 1
goto Prog1d
elseif (ButD = 1) and (LPsi > 5) then
LPsi = LPsi - 1
goto Prog1d
elseif (LPsi > 40) or (LPsi < 5) then
goto Prog1d
endif
do
loop while (ButU = 0) and (ButD = 0) and (ButT = 0)
if ButU = 1 then
pause 100
if (ButU = 1) and (ButD = 0) and (ButT = 0) then
if LPsi < 40 then
LPsi = LPsi + 1
endif
for b0 = 0 to 100
if ButU = 0 then
goto Prog1d
endif
pause 10
next b0
endif
endif
if ButD = 1 then
pause 200
if (ButD = 1) and (ButU = 0) and (ButT = 0) then
if LPsi > 10 then
LPsi = LPsi - 1
endif
for b0 = 0 to 100
if ButD = 0 then
goto Prog1d
endif
pause 10
next b0
endif
endif
if ButT = 1 then
pause 250
if ButT = 1 then
do
loop while ButT = 1
write 7,LPsi
goto Start_Screen
endif
endif
if (ButU = 1) or (ButD = 1) then
pause 250
if (ButU = 1) and (ButD = 1) then
goto Start_Screen
endif
endif
goto Prog1d


Load_Vars:
read 6,PTarg
arraywrite PTargA, [#PTarg]
read 7,LPsi
ARRAYWRITE LPsiA, [#LPsi]
read 10,CFG
return

CuriousOne
- 5th February 2022, 18:25
Thanks!
That looks promising!