it is. it's the driver component to enable my graphics library to use a sharp memory display.Quote:
Your lib file looks more like an example file. Is it correct ?
post #1 has typical use demos!
Printable View
it is. it's the driver component to enable my graphics library to use a sharp memory display.Quote:
Your lib file looks more like an example file. Is it correct ?
post #1 has typical use demos!
update to ssd1306 include to allow easier configuration for 40x72 displays
eg
Code:'****************************************************************'* Name : SSD1306 FOR PIC 18 DEMO *
'* Author : Richard *
'* Notice : *
'* : *
'* Date : 27/12/2023 *
'* Version : 1.0 *
'* Notes : *
'* :18f26k22 @64Mhz *
'****************************************************************
#CONFIG
CONFIG FOSC = INTIO67
CONFIG PLLCFG = ON
CONFIG PRICLKEN = ON
CONFIG FCMEN = OFF
CONFIG IESO = OFF
CONFIG PWRTEN = ON
CONFIG BOREN = SBORDIS
CONFIG BORV = 190
CONFIG WDTEN = ON
CONFIG WDTPS = 32768
CONFIG CCP2MX = PORTC1
CONFIG PBADEN = OFF
CONFIG CCP3MX = PORTB5
CONFIG T3CMX = PORTC0
CONFIG HFOFST = ON
CONFIG P2BMX = PORTB5
CONFIG MCLRE = EXTMCLR
CONFIG STVREN = ON
CONFIG LVP = OFF
CONFIG XINST = OFF
CONFIG DEBUG = OFF
CONFIG CP0 = OFF
CONFIG CP1 = OFF
CONFIG CP2 = OFF
CONFIG CP3 = OFF
CONFIG CPB = OFF
CONFIG CPD = OFF
CONFIG WRT0 = OFF
CONFIG WRT1 = OFF
CONFIG WRT2 = OFF
CONFIG WRT3 = OFF
CONFIG WRTC = OFF
CONFIG WRTB = OFF
CONFIG WRTD = OFF
CONFIG EBTR0 = OFF
CONFIG EBTR1 = OFF
CONFIG EBTR2 = OFF
CONFIG EBTR3 = OFF
CONFIG EBTRB = OFF
#ENDCONFIG
DEFINE OSC 64
;set these to match display
ssd1306_addr con $78
#DEFINE colours 1 ;1 mono 2 rg or 3 rgb
width con 72;128
height con 40;64
h_offset con 28
include "grx.pbpMOD"
include "SSD1306.pbpMOD"
include "Arial_Narrow18x39.bas"
' include "bignum.bas"
' include "bigchr.bas"
BUFF VAR BYTE[10]
J VAR word
ANSELB=0
ANSELC=0
ANSELA=0
OSCCON=$70
gosub glcd_init
gosub grf_clr
SETFONT Arial_Narrow18x39
gosub show
main:
while j <1000
colour=1
fillrect 0,0,72,40
ARRAYWRITE BUFF,[dec2 j/10,":",dec1 j,0]
DMDSTR 1,0,buff,0
gosub show
pause 10
j=j+1
wend
j=0
goto main
Nice and useful addition to a very handy include file.
Though I wonder up to what age you can read that displays without eye glasses...
Ioannis
that's kinda the purpose of this universal graphics method, fonts for it of a good size are simple to make and interchangeableQuote:
Though I wonder up to what age you can read that displays without eye glasses...
between versions and displays.
a 5x7 font on that display needs a magnifying glass and eye glasses for me.
note i used a 18x39 font to test with. that i can read from many metres away easily
bmp bug fix
Working much better, but in my case it is cropping 6 columns off of the right side of the image (110x64). Using the pbp file I uploaded here
Here are 2 images of what it should look like (using SSDBM vs what is being displayed using DMDBMP.
Attachment 9635 Attachment 9636
the bmp image width needs to be a multiple of 8 by the look of it
post the original bmp image if you want me to look further into it
Ok, I assume that is due to the horizontal vs vertical byte layout? I know on the SSDBM you said height must be multiple of 8 which I have been adhering to. I'll either stick to using the SSDBM with this driver as it seems to do exactly what I need or revise the bitmaps to make width a multiple of 8.
i have had a look at how those programs [lcdassist and glcd tool] manage the remainder bits when a bitmap is not an 8bit multiple in width
and it defeats me , i cannot get how the "stray" bits of the image width are packed into the data
if you lay the data out to match the actual width x height as i have done here
[the last column i filled in manually only partially to get an idea of what the data needs to look like ]
the "left over" 48 bytes at the end somehow represents the extreme rhs 6 bits , i don't see how to extract the data correctly.
6 bits * 48 bytes is 384 bits , the stray 6 bits of width x 64 lines of height is 384 bits so there is enough information at least.
[assuming i have not misconstrued the original image]
Code:
OneIcon: '110x64 horiz
@ db 112, 0x40
@ db 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,0xfc
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x04
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x04
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x04
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x04
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x04
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x04
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x04
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x04
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x04
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xF0, 0x00, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF8, 0x00, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x00, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x80, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xC0, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xE0, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xF0, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFC, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0x80 ,0
@ db 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0 ,0
@ db 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,0
@ db 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC ,0
@ db 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ,0
@ db 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ,0
@ db 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ,0
@ db 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ,0
@ db 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ,0
@ db 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ,0
@ db 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ,0
@ db 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ,0
@ db 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ,0
@ db 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ,0
@ db 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ,0
@ db 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ,0
@ db 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ,0
@ db 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x04
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x04
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x04
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x04
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x04
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x04
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x04
@ db 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x04
@ db 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,0xfc
'@ db 0xFC, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x03, 0x00, 0x01, 0x00, 0x04, 0x00
'@ db 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x01, 0x00, 0x11, 0x00, 0x00, 0x00, 0x18, 0x00, 0x01, 0x00
'@ db 0x1A, 0x00, 0x04, 0x00, 0x28, 0x00, 0x02, 0x00, 0x38, 0x00, 0x00, 0x00, 0x4A, 0x02, 0x00, 0x00
Is there a way to do 90 degree screen rotation (using the display in portrait mode) for the text using fonts to be displayed correct?
Changing the SSDc $20 address to $01 seems to corrupt everything, so I'm not sure if I am going down the correct path with that, or if there is a simple way to accomplish this already built in?
The display layout still isn't quite right. Here is a simple program that displays a 16x16 image in all 4 corners the ones on the left side are good, but the right side locations are wrong.
Attachment 9640 Attachment 9641 Attachment 9642 Attachment 9643Code:'PIC18F26K22
#CONFIG
CONFIG FOSC = INTIO67
CONFIG PLLCFG = ON
CONFIG PRICLKEN = ON
CONFIG FCMEN = OFF
CONFIG IESO = OFF
CONFIG PWRTEN = ON
CONFIG BOREN = SBORDIS
CONFIG BORV = 190
CONFIG WDTEN = ON
CONFIG WDTPS = 32768
CONFIG CCP2MX = PORTC1
CONFIG PBADEN = OFF
CONFIG CCP3MX = PORTB5
CONFIG T3CMX = PORTC0
CONFIG HFOFST = ON
CONFIG P2BMX = PORTB5
CONFIG MCLRE = EXTMCLR
CONFIG STVREN = ON
CONFIG LVP = OFF
CONFIG XINST = OFF
CONFIG DEBUG = OFF
CONFIG CP0 = OFF
CONFIG CP1 = OFF
CONFIG CP2 = OFF
CONFIG CP3 = OFF
CONFIG CPB = OFF
CONFIG CPD = OFF
CONFIG WRT0 = OFF
CONFIG WRT1 = OFF
CONFIG WRT2 = OFF
CONFIG WRT3 = OFF
CONFIG WRTC = OFF
CONFIG WRTB = OFF
CONFIG WRTD = OFF
CONFIG EBTR0 = OFF
CONFIG EBTR1 = OFF
CONFIG EBTR2 = OFF
CONFIG EBTR3 = OFF
CONFIG EBTRB = OFF
#ENDCONFIG
DEFINE OSC 64
clear
ssd1306_addr con $78
#DEFINE colours 1 ;1 mono 2 rg or 3 rgb
width con 128
height con 64
h_offset con 0
include "grx.pbpMOD"
include "SSD1306.pbpMOD"
BUFF VAR BYTE[32]
ANSELB=0
ANSELC=0
ANSELA=0
OSCCON=$70
OSCTUNE.6=1
gosub glcd_init
gosub grf_clr
gosub show
main: ' Rotate icon clockwise around display corners
DMDBMP 0,0,TestIcon 'top left 16x16 CORRECT PLACEMENT!
gosub show
pause 1000
gosub grf_clr
gosub show
DMDBMP 111,0,TestIcon 'top right 16x16 WRONT PLACEMENT!
gosub show
pause 1000
gosub grf_clr
gosub show
DMDBMP 111,47,TestIcon 'bottom right 16x16 WRONG PLACEMENT!
gosub show
pause 1000
gosub grf_clr
gosub show
DMDBMP 0,47,TestIcon 'bottom left 16x16 CORRECT PLACEMENT!
gosub show
pause 1000
gosub grf_clr
gosub show
goto main
end
TestIcon:
@ db 0x10,0x10 ;16x16
@ db 0xFF,0xFF;
@ db 0xC0,0x03;
@ db 0xA0,0x05;
@ db 0x90,0x09;
@ db 0x88,0x11;
@ db 0x84,0x21;
@ db 0x82,0x41;
@ db 0x81,0x81;
@ db 0x81,0x81;
@ db 0x82,0x41;
@ db 0x84,0x21;
@ db 0x88,0x11;
@ db 0x90,0x09;
@ db 0xA0,0x05;
@ db 0xC0,0x03;
@ db 0xFF,0xFF;
bmp placement fixed , note that horiz placement is byte aligned ie for a 128 bit wide display there are 16 bytes therefore 16 positions max
Excellent! All seems to be working perfectly!
Now, how can I rotate the display for use in portrait mode?
in theory portrait mode should be easier and faster than what i have now, the screen width 64 height 128
and the buffer sent to the screen in horiz fill mode nice and sequentially [ might need bit reversal, could be upside down or mirrored]
i will have a look one day time permitting
a portrait version
Attachment 9645
Code:
'*******************************************************************
'* Name : SSD1306p.pbpmod *
'* Author : richard *
'* Notice : Copyright (c) 2021 *
'* : *
'* Date : 28/12/2023 *
'* Version : 1.1 *
'* Notes : generic GRX graphics DRIVER FOR SSD1306 *
'* : HW I2C PIC18 ONLY *
'* : 40x72 disp added *
'* : portrait version *
'* : *
'* : *
'**********************************************************************
;set these to match display IN MAIN
' ssd1306_addr con $78
' #DEFINE colours 1 ;1 mono 2 rg or 3 rgb
' width con 128
' height con 32
' h_offset con 0 ;28 for 40x72
glrot var byte[8]
glrb var byte[8]
gltmp var byte[3]
glcd_rad var WORD
glcdData VAR byte 'DATA
glcdBC VAR BYTE 'gca var
page VAR WORD 'gca var
gy var byte 'gca pg address
gy_ var byte 'gca pg address
gx var byte 'gca row address
gx_ var byte 'gca row address
ssd_add var byte
USERCOMMAND "SENDBYTE" ;BYTE
USERCOMMAND "SSDC" ;cmd BYTE TO SSD1306
ssdheight con WIDTH/8-1 ; 7 = 8 PAGES 64*128 , 3 = 4 pages 32*128
ssdwidth con HEIGHT-1 ; 128 PIXELS WIDE
goto overssd
ASM
SSDC?C macro Cin
MOVE?CB Cin , _glcdData
L?CALL _cmd_byte
endm
SSDC?B macro Cin
MOVE?BB Cin , _glcdData
L?CALL _cmd_byte
endm
SENDBYTE?B macro Dat
MOVE?BB Dat ,_glcdData
L?CALL _send_byte
endm
SENDBYTE?W macro Dat
MOVE?WB Dat ,_glcdData
L?CALL _send_byte
endm
SENDBYTE?C macro Dat
MOVE?CB Dat ,_glcdData
L?CALL _send_byte
endm
ENDASM
glcd_init:
bgcolour = 0
colour = 1
SSPSTAT = 0 'High Speed Filter
SSPADD = $14'400 kHz @64 MHz ?
SSPCON1 = 101000 'I2C Master Mode Enable
SSPCON3 = 0
ssd_add = ssd1306_addr
SSDc $AE ' Display OFF
SSDc $d5
SSDc $80
SSDc $a8 : SSDc $3f
SSDc $D3 : SSDc $00 ; Set Display Offset Mode Set 0
if ssdheight > 4 then
SSDc $40 ' Set display start line 0
elseif ssdheight > 3 then
SSDc $68 ' Set display start line
else
SSDc $60 ' Set display start line 4
endif
SSDc $8D : SSDc $14 ' Set Charge Pump Internal
SSDc $20 : SSDc $01 ' Adressing mode Horizontal
SSDc $A1 ' set segment remap column 127 as start
SSDc $C0 ' Com Scan Direction, Flip display vertically
SSDc $DA ' set COM pins
if ssdheight > 3 then
SSDc$12 ' set COM pins = 128x64=$12
else
SSDc$02 ' set COM pins = 128x32=$02
endif
SSDc $81 : SSDc$7F ' Set brightness to $01 to $FF ($7F is default, $01 is faint)
SSDc $DB : SSDc$40 ' Set VCOM Deselect Level
SSDc $B0 ' Set Page Address From $B0 to $B7
SSDc $2e ; scroll off
SSDc $A4 ' display ON continue
SSDc $A6 ' $A6=NORMAL MODE; $A7=INVERSE MODE
SSDc $AF ' Display ON
return
show:
' gosub flip
SSDc $22
SSDc 0
SSDc ssdheight
SSDc $21
SSDc h_offset
SSDc ssdwidth + h_offset
SSPCON2.0 = 1 ; SEN - Start Condition Enable Bit
WHILE SSPCON2.0 = 1 : WEND ; Wait for Start to complete
SSPBUF = ssd_add ; Move data to SSPBUF
WHILE SSP1STAT.2 = 1 : WEND ; SSPSTAT = 1 Transmit in progress
While SSP1CON2.6 = 1 : WEND ; Wait for Acknowledge from slave
SSPBUF = $40 ; Move data to SSPBUF
WHILE SSPSTAT.2 = 1 : WEND ; SSPSTAT = 1 Transmit in progress
While SSPCON2.6 = 1 : WEND ; Wait for Acknowledge from slave
for glcd_rad = 0 to width/8 * height -1
SENDBYTE fbr[glcd_rad ]
next
SSPCON2.2 = 1
' gosub flip
return
send_byte : 'DATA
SSPBUF = glcdData; Move data to SSPBUF
WHILE SSPSTAT.2 = 1 : WEND ; SSPSTAT = 1 Transmit in progress
While SSPCON2.6 = 1 : WEND ; Wait for Acknowledge from slave
return
cmd_byte: 'send command sequence "glcdData "
SSPCON2.0 = 1 ; SEN - Start Condition Enable Bit
WHILE SSPCON2.0 = 1 : WEND ; Wait for Start to complete
SSPBUF = ssd_add ; Move data to SSPBUF
WHILE SSPSTAT.2 = 1 : WEND ; SSPSTAT = 1 Transmit in progress
While SSPCON2.6 = 1 : WEND ; Wait for Acknowledge from slave
SSPBUF = 0 ; Move data to SSPBUF
WHILE SSPSTAT.2 = 1 : WEND ; SSPSTAT = 1 Transmit in progress
While SSPCON2.6 = 1 : WEND ; Wait for Acknowledge from slave
SSPBUF = glcdData ; Move data to SSPBUF
WHILE SSPSTAT.2 = 1 : WEND ; SSPSTAT = 1 Transmit in progress
While SSPCON2.6 = 1 : WEND ; Wait for Acknowledge from slave
SSPCON2.2 = 1 ; PEN - send stop bit
While SSP1CON2.2 = 1 : Wend ; Wait for SSP to complete
return
overssd:
with demo
Code:'PIC18F26K22#CONFIG
CONFIG FOSC = INTIO67
CONFIG PLLCFG = ON
CONFIG PRICLKEN = ON
CONFIG FCMEN = OFF
CONFIG IESO = OFF
CONFIG PWRTEN = ON
CONFIG BOREN = SBORDIS
CONFIG BORV = 190
CONFIG WDTEN = ON
CONFIG WDTPS = 32768
CONFIG CCP2MX = PORTC1
CONFIG PBADEN = OFF
CONFIG CCP3MX = PORTB5
CONFIG T3CMX = PORTC0
CONFIG HFOFST = ON
CONFIG P2BMX = PORTB5
CONFIG MCLRE = EXTMCLR
CONFIG STVREN = ON
CONFIG LVP = OFF
CONFIG XINST = OFF
CONFIG DEBUG = OFF
CONFIG CP0 = OFF
CONFIG CP1 = OFF
CONFIG CP2 = OFF
CONFIG CP3 = OFF
CONFIG CPB = OFF
CONFIG CPD = OFF
CONFIG WRT0 = OFF
CONFIG WRT1 = OFF
CONFIG WRT2 = OFF
CONFIG WRT3 = OFF
CONFIG WRTC = OFF
CONFIG WRTB = OFF
CONFIG WRTD = OFF
CONFIG EBTR0 = OFF
CONFIG EBTR1 = OFF
CONFIG EBTR2 = OFF
CONFIG EBTR3 = OFF
CONFIG EBTRB = OFF
#ENDCONFIG
DEFINE OSC 64
clear
ssd1306_addr con $78
#DEFINE colours 1 ;1 mono 2 rg or 3 rgb
width con 64
height con 128
h_offset con 0
DEFINE DEBUG_REG PORTB
DEFINE DEBUG_BIT 7
DEFINE DEBUG_BAUD 9600
DEFINE DEBUG_MODE 0
LATB.7=1
trisb.7=0
include "grx.pbpMOD"
include "SSD1306p.pbpMOD"
include "font.bas"
BUFF VAR BYTE[32]
ANSELB=0
ANSELC=0
ANSELA=0
OSCCON=$70
OSCTUNE.6=1
SETFONT FONT5x7
gosub glcd_init
main:
gosub grf_clr
gosub show
ARRAYWRITE BUFF,["GLCD",0]
DMDSTR 3,75,buff,1
DMDBMP 0,0,TestIcon
gosub show
pause 5000
goto main
end
TestIcon:
@ db 0x10,0x10 ;16x16
@ db 0xFF,0xFF;
@ db 0xC0,0x03;
@ db 0xA0,0x05;
@ db 0x90,0x09;
@ db 0x88,0x11;
@ db 0x84,0x21;
@ db 0x82,0x41;
@ db 0x81,0x81;
@ db 0x81,0x81;
@ db 0x82,0x41;
@ db 0x84,0x21;
@ db 0x88,0x11;
@ db 0x90,0x09;
@ db 0xA0,0x05;
@ db 0xC0,0x03;
@ db 0xFF,0xFF;
Excellent work Richard!!!
This will work well for my use, but with a little more tweaking it would be nice to have a define to set 1 of 4 different viewing directions to make a more universal driver.
Hi Richard,
I've been using your display drivers with 12864 ST7920 LCDs and one thing that's annoying (for me) is randomly on startup I'll be getting 3 large(ish) zeros in the top left corner of the display. If they appear, there's no getting rid of them without cutting power to the display. Any idea what I'm missing here? I can still write stuff to the display, but the zeros will remain there irrespective of screen clearing. Even filling the screen with a filled (black) rectangle - the zeros are still there but just colour inverted.
You can see if they're going to appear with the initialisation call to st7920_init as the areas around there is more populated with random dots than neighbouring areas. Sometimes it's clear enough to make them out before calling a screen clear and show.
Could this be a timing problem on my initialisation? It's happened on various displays (same model) and various completely different programs.
Troy
most likely, the displays have two screen memory regions one for graphics the other for the normal lcd character displayQuote:
Could this be a timing problem on my initialisation?
at power up display is in lcd mode, the init routine sets it to graphics, lcds are slow to powerup they cannot be hurried.
if the display is written to before graphics mode is established then its possible some lcd chrs will be displayed accidently.
lcd chrs can only be cleared if the display is in lcd mode , graphic pixels can only be set in graphics mode
both memories are visible on screen no matter what mode is set.
Yeah, what you've said does make sense. I've played around with all sorts of timings - like up to 10s pause after calling the st7920_init and 2s prior, but I don't think it's my writing to the display that's causing the issue as the signs are already there when I call st7920_init.
So, are you aware of any commands I can call to initialise the "character" memory before calling st7920_init?
Thanks,
Troy
as in my demo
Code:
Pause 1500 ' LCD initialize time
lcdout $FE,1
gosub st7920_init 'graphic mode
[mega facepalm] DUH!!!
Thanks Richard.
Troy
Well, the zeros are still appearing even with up to 5 consecutive commands to clear the character memory. However, probably not as often. Definitely is text in the character display memory that's causing it - no doubt about it, but I'm also sure I'm doing something wrong with either the wiring or initialisation. Probably tolerable for now.
Troy
at one stage i did init like this
st7920_init:
lcdout $FE,$24 'In same instruction cannot alter DL, RE and G at once. Make sure that change DL or G first and then RE.
Pause 5
lcdout $FE,$26
Pause 5
bgcolour = 0
colour = 1
return
also look at defines' these may need a fiddle if you display is slower than mine
DEFINE LCD_COMMANDUS 1000 'defines the delay after LCDOUT statement DEFINE LCD_DATAUS 40 'delay in micro seconds
ps i changed to serial mode, perhaps thats why , i forget
No luck. Maybe 1 in 10 starts I still get the zeros. Tried increasing the DEFINE LCD_COMMANDUS 1000 to 1500 and DEFINE LCD_DATAUS to 100 and inserted the code you suggested. I didn't mention I need to call the graphic mode initialisation routine a few times to get a reasonably reliable initialisation which might trigger alarm bells? So, my hunch is the display might be slightly different or my wiring is missing something: I've wired up RS, E, RW and the 4 high bits of the data bus and 5V rails. I can't think of anything else?
Troy
does it make a difference if you power it down verses a reset >\?
also if you look at the data sheet you can see what commands are needed to make a routine to revert to lcd mode, do a clear screen then return to graphics mode
Haven't tried 1st suggestion yet, but I've been playing around with your 2nd suggestion... well... I can't find a datasheet for my displays so I've been playing the old game of finding a ST7920 DS with commands that might be close enough. So, I found one that lists a command that turns the graphics display on / off. So, I've tried simulating the issue and it goes like this:
init code
...
run some st7920_init calls with pauses
...
...
your extra LCD commands...
...
pause 1000
lcdout $FE, %00100100 'Command to turn off graphics mode
pause 1000
lcdout $FE,1,"123" 'clear screen and display 123 in top left corner in text mode - the numbers 123 *are* displayed in the top left
pause 1000
lcdout $FE,1 'Clear screen for text mode - screen *is* cleared
pause 1000
lcdout $FE, %00100110 'command to turn graphics mode back on - screen still cleared (replacing this with "gosub st7920_init" produces the same outcome)
gosub grf_clr 'clear graphics display
colour = 1
FILLRECT 5,35,120,8
ARRAYWRITE BUFF2,["WAITING FOR LOAD CELL",0]
DMDSTR 5,10, BUFF2,1
ARRAYWRITE BUFF3,["SERIAL STREAM",0]
DMDSTR 5,25, BUFF3,1
gosub show 'here the stuff just here (supposed to be displayed) is displayed BUT my 123 text in the top left has also reappeared which is supposed to be cleared whilst in text mode
?????
if you are using 4 bit mode for lcd then the DL bit must remain unset in the command
my code assumes 4 bit mode
to get to lcd mode RE bit must be 0
so more like
lcdout $FE, %00100010 'command to turn extended command set off ; might need to swap ext/gph around of maybe they can be done together - not sure
pause 5
lcdout $FE, %00100000 'Command to turn off graphics mode
pause 5
lcdout $FE,1,"123" 'clear screen and display 123 in top left corner in text mode - the numbers 123 *are* displayed in the top left
pause 1000
lcdout $FE,1 'Clear screen for text mode - screen *is* cleared
pause 5
lcdout $FE, %00100100 'command to turn extended command set on ; we know this works
pause 5
lcdout $FE, %00100110 'command to turn graphics mode back on
outcome)
Thanks Richard. I had to park the project since Friday but I've just reopened it and I can see my mistake: as you said, the RE bit was the killer in my character mode command. Seems to be clearing okay now :)
Cheers,
Troy
Now have driver for P10 rbg Panels
here is demo for 8x 32x16 panels in a 128x32 pixel array 1200x400mm in size
https://youtu.be/83BbeNs-zlk
Great job Richard!
Now this is a big panel, isn't it!
Seems there is an error in the word DEMO. Looks like DEMC
Ioannis
Very impressive! That looks like many hours of work. Are you using the WS2812 LEDs?
Hey Richard, just out of curiosity, is this written in PIC Basic? I’m guessing probably not. Either way, good job!
In the meantime, I’ve switched from Basic to C and to the RISC-V architecture.
But from time to time, I like to look in here to see what’s new.
This forum gave me a lot of useful information, for which I’m grateful, so I’m glad it’s still active and alive here.
Louis
one thing i cannot master is taking a video of led displays that shows the true colours especially if the display is multiplexedQuote:
Ioannis
Seems there is an error in the word DEMO. Looks like DEMC
there is no error the camera does lie
at 512 pixels per panel * 8 panels * 3 colours [24 bits] per pixel = 12288 bytes , no 8 bit pic to date has that much memory so no,Quote:
rsocor01
Are you using the WS2812 LEDs?
google "p10 rgb led module"
thats 3 bits per pixel or 1536 bytes but 1/4 scan multiplexing needed [the panels come in various flavors of multiplexing format]
my code only supports AB zigzag format
yes it is in pbp3, although crucial bits that need speed are done in asm code. its customized to run on pic18fxxk22 seriesQuote:
Louis
Hey Richard, just out of curiosity, is this written in PIC Basic? I’m guessing probably not. Either way, good job!
In the meantime, I’ve switched from Basic to C and to the RISC-V architecture.
But from time to time, I like to look in here to see what’s new.
This forum gave me a lot of useful information, for which I’m grateful, so I’m glad it’s still active and alive here.
it can support 1 to 8 panels
i do have better C versions that support up to 10 panels in xc8 or xc16 running pic18f47q43 and PIC24FJ128GA204
one panel
https://youtu.be/ADqMRU4rcBg
Does anyone know how to work with these small SPI displays that use st7789v driver?
These are very small but seem to have lot's of potential.
https://aliexpress.com/item/1005005350081640.html