you cannot, the smallest element is 1 byte ie one column[page] of 8 rows
Printable View
you cannot, the smallest element is 1 byte ie one column[page] of 8 rows
Right, so you are talking about using data in a more efficient way using the vertical display mode as described in figure 10-4, correct?Quote:
you cannot
Attachment 9500
yes , aligning the font data packing with the ssd1306's memory page layout is more efficient usage of the 14 bit width of the flash memory
while it will still need some clever manipulation to unpack it into a 8 bit data stream
Attachment 9501
Okay, found!
Attachment 9502
Here is a simple code to get started with this 72x40 display.
I also include the SSD1306 command and display's datasheets.
Since I use EXCEL to design characters, here's the sheet you may want to have a look at.
And again, lots of thanks to Richard :wink:
Attachment 9504
You seem to have the communication to the controller well under control
next step is to try to store a font economically, you have probably discovered a large font on a very resource limited chip
like a 690 stored as a series of code structures like
I2CWrite SDA,SCL,I2CDevice,_
[$40,192,224,240,248,252,126,63,63,63,63,63,63,63,6 3,126,252,248,240,224,192,_
255,255,255,255,128,128,128,128,128,128,128,128,12 8,128,128,128,255,255,255,255,_
255,255,255,255,15,15,15,15,15,15,15,15,15,15,15,1 5,255,255,255,255,_
255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,25 5,255]
will by the time you have 10 digits covered will have blown 75% of the chips flash.
fonts can be stored in much better ways, even expanded out as the are read back
Richard, can you point me the direction to do this?Quote:
fonts can be stored in much better ways
Should I use some kind of algorithm where repetitive numbers could be stored differently or find a way to make better use of the 14 bits word size of the 16F690?
the font is just a simple block of data
this one is for digits 0 to 9 + "." + "%" its 14 bits high and 10 bits wide [to match chip flash]
so total size is 120 words
for convenience lets locate it a the end of flash - 120 words ie. 0xf88
note this is only partially "filled" in and not very carefully at that
normally i would make the font an include and give it a label rather than manually locate it like thisCode:asm ;incomplete and very rough font 14x10
org 0xf88
dw 0x1ffc,0x3ffe,0x3006,0x3006,0x3006,0x3006,0x3006,0x3006,0x3ffe,0x1ffc ;"0"
dw 0,0x300C,0x300E,0x300F,0x3ffF,0x3ffF,0x3ffF,0x3000,0x3000,0
dw 0x3806,0x3C07,0x3E03,0x3703,0x3383,0x31E3,0x30F3,0x307F,0x303E,0
dw 0x3018,0x3006,0x3186,0x3186,0x3186,0x3186,0x3186,0x3006,0x3cf8,0x1ffc ;"3"
dw 0,0x3ffe,0,0x3ffe,0,0x3ffe,0,0x3ffe,0,0
dw 0,0x3ffe,0,0x3ffe,0x3ffe,0x3ffe,0,0x3ffe,0,0
dw 0x3ffe,0x3ffe,0x3ffe,0,0,0,0,0x3ffe,0x3ffe,0x3ffe
dw 0x3ffe,0x3ffe,0x3ffe,0,0,0x3ffe,0,0x3ffe,0x3ffe,0x3ffe
dw 0x1ffc,0x3ffe,0x3186,0x3186,0x3186,0x3186,0x3186,0x3186,0x3ffe,0x1ffc ;"8"
dw 0,0x3ffe,0x3ffe,0x3ffe,0x3ffe,0x3ffe,0x3ffe,0x3ffe,0x3ffe,0x3ffe
dw 0,0,0,0xE00,0x1F00,0x1F00,0xE00,0,0,0 ;"."
dw 0x181f,0xC11,0x611,0x31f,0x1C0,0x60,0x1F38,0x110c,0x1106,0x1F02 ;"%"
endasm
dt's macro as found in dt-ints is ideal to find and numerate the font address
when the fonts address is known its simple to use readcode command to retrieve font dataQuote:
GetAddress macro Label, Wout
CHK?RP Wout
movlw low Label ; get low byte
movwf Wout
movlw High Label ; get high byte
movwf Wout + 1
endm
Just for fun, scrolling text example :wink:
Attachment 9511
i'm not seeing a font , i had a look at a 40x18 font this morning with my new 72x40 that just arrived
encoded this way seems the best compromise for easy of unpacking into a 18 x 5 byte stream to send to display
Attachment 9512
Attachment 9513
i dont like most of you inital sfr settings
i would replace the entire section with
OSCCON = $70 ;% 01110000 'Internal RC set to 8MHZ
for these reasons
OPTION_REG = % 10000000 'PORT A&B Pull-Ups disabled (see WPUA & WPUB)
Pull-Ups are set that way by default anyway . that does other things to that may later prove to be incorrect Like set int edge to falling, reassign and alter the prescaler, change timer 0 clock source
OSCCON = % 11100000 'Internal RC set to 8MHZ
no 'OSCCON = % 01110000 for 8mhz you have set it for 4 mhz
ANSEL = % 00010100 'Select analog inputs Channels 0 to 7 (AN2 + AN4 selected)
ok but you then go on to make those pins be digital outputs , not recommended except for smoke generation if used as analog inputs
ADCON0 = % 10000000 'A/D Module (Bit5:2 select channels 0:11)
ADCON1 = % 00000000 'A/D control register
why ? makes no sense adc is off by default
CM1CON0 = % 00000000 'Comparator1 Module is OFF
CM2CON0 = % 00000000 'Comparator2 Module is OFF
why ? Comparator 1 and 2 Modules are OFF by default
INTCON = % 00000000 'INTerrupts CONtrol (TMR0 OFF)
why serves no purpose ints are off by default
TRISA = % 00000000 'Set Input/Output (0 to 5)
bad call when an2
TRISB = % 00000000 'Set Input/Output (4 to 7)
bad call when 4,6 used for i2c
TRISC = % 00000000 'Set Input/Output (0 to 7)
bad call when an4
why ? i2c pins can left as be inputs
when breadboarding leave unused pins as inputs. fine set them as low outputs for the "production" version if a few microwatts of power dissipation makes a difference
PORTB = % 00000000 'Ports High/Low (4 to 7)
why ? i2c pins being set low is not useful
i have tried a 14x10 , a 14x10 doubled to 28x20
a 13x7 doubled to 26x14 and tripled to 39x21
they all work ok. imho by leaps and bounds a 40x18 full size font looks best and is only 540 words for ten digits
https://youtu.be/_blpLnHxYH8
Richard,
You're absolutely right about the useless register settings I mention in my code.
Most of them, if not all, just reflect their default state as per datasheet.
This is because I use a pic specific template so they are there everytime I start a new project and ready to be deleted in case of no use :wink:
BTW, your video looks great!! :cool:
Yes, I agree, this is definitively the hardest part to get it work.
Richard, how did you come to this $68 value please? I can't figure it out :confused:
Attachment 9514
'======= SSD1306 I2C OLED initialization ================================================== =========
COM = $AE : GOSUB SEND_COMMAND ' turn off OLED panel
COM = $D5 : GOSUB SEND_COMMAND ' set display clock divide ratio/oscillator frequency
COM = $F0 : GOSUB SEND_COMMAND ' set divide ratio
COM = $A8 : GOSUB SEND_COMMAND ' set multiplex ratio
COM = $27 : GOSUB SEND_COMMAND ' 1/40 duty
COM = $D3 : GOSUB SEND_COMMAND ' set display offset
COM = $00 : GOSUB SEND_COMMAND
COM = $40 : GOSUB SEND_COMMAND ' set display start line
COM = $8D : GOSUB SEND_COMMAND ' set Charge Pump enable/disable
COM = $14 : GOSUB SEND_COMMAND ' set(0x10) disable
COM = $20 : GOSUB SEND_COMMAND ' Addressing Setting Command Table
COM = $00 : GOSUB SEND_COMMAND ' Page Addressing Mode
COM = $A1 : GOSUB SEND_COMMAND ' set segment re-map: column address 127 is mapped to SEG0
COM = $C8 : GOSUB SEND_COMMAND ' Set COM Output Scan Direction 64 to 0
COM = $DA : GOSUB SEND_COMMAND ' set com pins hardware configuration
COM = $12 : GOSUB SEND_COMMAND ' Sequential COM pin configuration
COM = $AD : GOSUB SEND_COMMAND ' Internal IREF Setting
COM = $30 : GOSUB SEND_COMMAND ' --
COM = $81 : GOSUB SEND_COMMAND ' set contrast control register
COM = $2F : GOSUB SEND_COMMAND ' set contrast value 0..255
COM = $D9 : GOSUB SEND_COMMAND ' set pre-charge period
COM = $22 : GOSUB SEND_COMMAND ' set pre-charge value
COM = $DB : GOSUB SEND_COMMAND ' set vcomh deselect level
COM = $20 : GOSUB SEND_COMMAND ' set vcomh value
COM = $A4 : GOSUB SEND_COMMAND ' Disable Entire Display On
COM = $A6 : GOSUB SEND_COMMAND ' set normal display
COM = $0C : GOSUB SEND_COMMAND ' set lower column address
COM = $11 : GOSUB SEND_COMMAND ' set higher column address
COM = $68 : GOSUB SEND_COMMAND ' set display start line register
COM = $AF : GOSUB SEND_COMMAND ' turn on OLED panel
the info supplied with the display makes calculating the value somewhat difficult . in fact i cannot see the connection at allQuote:
Richard, how did you come to this $68 value please? I can't figure it out
the command basically sets where the memory line representing page 0 bit 0 maps to the physical display top row pixels, it can be vertically offset by 0 to 63 pixels in a virtually identical way to the way the display scrolls horizontally
it needed to be offset by -23 pixels to get the top row to align with page 0 bit 0
command range = 0x40 to 0x7f , 0x7f - 23 = 0x68
Well, I think I'm just gonna remember this settings "as is".
Thanks for trying to make things more clear for me :wink:
This is very interesting thread, giving me some hope that I will be able to use OLED screens with PBP one day, but I have a quesiton - 24C64 or something like that costs under $1. Why not use it for font storage?
Quote:
I have a quesiton - 24C64 or something like that costs under $1. Why not use it for font storage
because you can save your $1 and another one by buying a better pic to start with and :-
not have a costlier more complex circuit board .
use a standard font file generated by glcd font creator.
its faster, uses hardware i2c and can do proper graphics too.
as i said at the beginning if you want easy get a pic 18
Attachment 9515
So expensive :)
I'm buying 2nd hand 886 and 1829 for about 50 and 90 cents in China :)
Since I'm not doing anything commercial, this is just fine for me.
And by the way, I don't see any reasons, why you can't write GLCD (which can't save file on windows 10-11) generated or any other software generated font into external EEPROM.
Nor do I , but I have never come anything to make a bin or hex file easily from the generated codeQuote:
don't see any reasons, why you can't write GLCD generated or any other software generated font into external EEPROM.
mine works perfectly win 10 and 11 , make sure to add the .lcd extension to the file name when saving it otherwise it goes funnyQuote:
(which can't save file on windows 10-11)
Because this thread will be followed with "how can I speed up my OLED display routines?".Quote:
Why not use it for font storage?
The choice is obviously yours, but the 18F27Q43 has 128K of flash, 8K of ram, and runs at 64MHz.
The only downside is the hardware I2C peripheral isn't compatible with the old MSSP I2C, so you're stuck using PBP's software I2CWRITE/I2CREAD or rolling your own (which is not trivial for these new parts).
Hi Richard, & all others in the post.
I've just started out with my OLED display, writing in PIC assembler so I'm presently reading the fine-print on the SSD1306 datasheet to ensure I leave no bits un-turned. I'm cross-referencing my program to others I've found, albeit none in assembler, as such I joined the forum to maybe smooth any glitches I stumble across as this discussion seems rather detailed.
Although the datasheet shows an approximate Initialise flowchart, I've noticed a few differences (in order) between some of the subroutines I've found:
An interesting one within the datasheet informs the Set-Charge-Pump command (8Dh) should be followed by the Display On (AFh) command, has yours been okay as such in your Richard?
Your 'set lower column address' & 'set higher column address', should these variables not be preceded with the actual 'Set Column Address' command, 21h?
Also, the 'Internal IREF Setting' command ($AD) , where in the datasheet is that command listed, I can find ample references to the Iref current & the calcs etc but can'f find the actual command.
If your sequence has proved okay, I'll use its order as a reference to set mine up, although I'll set Segment-0 as column-0 just to get it up & running then make changes as required.
Albeit writes to my CGRAM showed a blank display, as such I've yet to find if it's either my I2C timing (I'm bit banging), (OR) my actual programming sequence, hence firstly confirming the Initialise sequence.
This is my sequence;
0AEh ; Set Display OFF. AE h = display OFF, while AF= display ON.
0D5h ; Set Display Clock Divide Ratio/ Oscillator Frequency.
80h ; (value)
0A8h ; Set Multiplex Ratio.
3Fh ; (value)
40h ; Set Display Start Line (row) 0 - 63 (40h 7Fh). [as I'm using the 64x32 display]
20h ; Set Memory Addressing Mode;
00h ; Three choices, I use the Horizontal mode.
21h ; Set Column Address;
00h ; Column start address (0 for me)
3Fh ; Column end address (63 for me) [as I'm using the 64x32 display]
22h ; Set Page Address;
00h ; PAGE start address (0 for me).
03h ; PAGE end address (3 for me). [as I'm using the 64x32 display]
81h ; Set Contrast Control.
0CFh ; (value)
0D9h ; Set Pre-charge period.
0F1h ; (value)
0DBh ; Set VCOMH Deselect Level.
40h ; (value)
0A4h ; Entire display on. A4h= Display as per RAM content. A5h= Display is ON, **BUT** unafected by changes to RAM content.
0A6h ; Set Normal/Inverse Display. A6h= normal, A7h= inverse.
0x8D ; Set charge pump;
0x14 ; (value) - ON
0AFh ; Turn Display ON.
Mark.
------------
'======= SSD1306 I2C OLED initialization ================================================== =========
COM = $AE : GOSUB SEND_COMMAND ' turn off OLED panel
COM = $D5 : GOSUB SEND_COMMAND ' set display clock divide ratio/oscillator frequency
COM = $F0 : GOSUB SEND_COMMAND ' set divide ratio
COM = $A8 : GOSUB SEND_COMMAND ' set multiplex ratio
COM = $27 : GOSUB SEND_COMMAND ' 1/40 duty
COM = $D3 : GOSUB SEND_COMMAND ' set display offset
COM = $00 : GOSUB SEND_COMMAND
COM = $40 : GOSUB SEND_COMMAND ' set display start line
COM = $8D : GOSUB SEND_COMMAND ' set Charge Pump enable/disable
COM = $14 : GOSUB SEND_COMMAND ' set(0x10) disable
COM = $20 : GOSUB SEND_COMMAND ' Addressing Setting Command Table
COM = $00 : GOSUB SEND_COMMAND ' Page Addressing Mode
COM = $A1 : GOSUB SEND_COMMAND ' set segment re-map: column address 127 is mapped to SEG0
COM = $C8 : GOSUB SEND_COMMAND ' Set COM Output Scan Direction 64 to 0
COM = $DA : GOSUB SEND_COMMAND ' set com pins hardware configuration
COM = $12 : GOSUB SEND_COMMAND ' Sequential COM pin configuration
COM = $AD : GOSUB SEND_COMMAND ' Internal IREF Setting
COM = $30 : GOSUB SEND_COMMAND ' --
COM = $81 : GOSUB SEND_COMMAND ' set contrast control register
COM = $2F : GOSUB SEND_COMMAND ' set contrast value 0..255
COM = $D9 : GOSUB SEND_COMMAND ' set pre-charge period
COM = $22 : GOSUB SEND_COMMAND ' set pre-charge value
COM = $DB : GOSUB SEND_COMMAND ' set vcomh deselect level
COM = $20 : GOSUB SEND_COMMAND ' set vcomh value
COM = $A4 : GOSUB SEND_COMMAND ' Disable Entire Display On
COM = $A6 : GOSUB SEND_COMMAND ' set normal display
COM = $0C : GOSUB SEND_COMMAND ' set lower column address
COM = $11 : GOSUB SEND_COMMAND ' set higher column address
COM = $68 : GOSUB SEND_COMMAND ' set display start line register
COM = $AF : GOSUB SEND_COMMAND ' turn on OLED panel
no , that is setting the offset of the actual display as it is overlaid into the memory mapQuote:
Your 'set lower column address' & 'set higher column address', should these variables not be preceded with the actual 'Set Column Address' command, 21h?
its probably not a command at all but a data value that followed the contrast command that's become dislodged in space and time.Quote:
Also, the 'Internal IREF Setting' command ($AD) , where in the datasheet is that command listed, I can find ample references to the Iref current & the calcs etc but can'f find the actual command.
I've just realised I'd wrote your name Richard, instead of Rogers, as it was his initialisation listing I was querying, no worry.
I see one of Roger's later posts shows the two subsequent bytes, as with the subsequent Page Address command ($22) two bytes.
https://blogger.googleusercontent.co...30/Capture.JPG
The Internal IREF Setting' command ($AD), appears to be listed on older pdf's for the 72x40 type(?), a command not required on later board as set by a resistor.
I've sorted my glitch out, copying a double-byte send I2C section to create the triple byte I'd overlooked the unwanted I2C_Stop call before sending the 3rd byte, so was never seeing it.
Code:;======
call I2C_Start
call I2C_Address
movlw 00h ; 00=Command stream.
movwf I2C_Command_or_Data
call I2C_byte
movlw 21h ;Column Address;
movwf I2C_Command_or_Data
call I2C_byte
movlw 00h ; Low column.
movwf I2C_Command_or_Data
call I2C_byte
movlw 3Fh ; High column.
movwf I2C_Command_or_Data
call I2C_byte
call I2C_Stop
;
;======
call I2C_Start
call I2C_Address
movlw 00h ; 00=Command stream.
movwf I2C_Command_or_Data
call I2C_byte
movlw 22h ;[3] Page Address;
movwf I2C_Command_or_Data
call I2C_byte
movlw 00h ; Start page.
movwf I2C_Command_or_Data
call I2C_byte
movlw 03h ; End page.
movwf I2C_Command_or_Data
call I2C_byte
call I2C_Stop
;
I2C_Start
;-- Start --
bcf PORTA,SDA ;START commence,
call _nops
bcf PORTA,SCK ; START complete.
return
I2C_Address
;-- Address_byte -- ;= 78h (bit [0] = R/W. Writing, so = 0.
bcf PORTA,SDA ;bit 7
call clk_it
bsf PORTA,SDA ;bit 6
call clk_it
bsf PORTA,SDA ;bit 5
call clk_it
bsf PORTA,SDA ;bit 4
call clk_it
bsf PORTA,SDA ;bit 3
call clk_it
bcf PORTA,SDA ;bit 2
call clk_it
bcf PORTA,SDA ;bit 1
call clk_it
bcf PORTA,SDA ;bit 0 (R/W bit)
call clk_it
; return
;
I2C_Ack
;-- Ack --
bsf STATUS,RP0 ;Page 1.
bsf TRISA,SDA ;Set as input to release the line
bcf STATUS,RP0 ;Page 0.
call clk_it
bsf STATUS,RP0 ;Page 1.
bcf TRISA,SDA ;Set back to output.
bcf STATUS,RP0 ;Page 0.
return
;
I2C_byte
;-- Command or Data byte --
movlw 08h
movwf countbits ;count the 8 bits RLF
byte_bits
btfss I2C_Command_or_Data,7
goto low_bit1
bsf PORTA,SDA
goto _clk1
low_bit1
bcf PORTA,SDA
_clk1 call clk_it
decfsz countbits,same
goto _rlf
goto I2C_Ack ;return
_rlf rlf I2C_Command_or_Data
goto byte_bits
;
I2C_Stop
;-- Stop --
bcf PORTA,SDA ;Before STOP, ensure its low.
call _nops
bsf PORTA,SCK ;STOP commence,
call _nops
bsf PORTA,SDA ; STOP completed.
; call _nops
call d50mS
return ;I2C over.
For any reason, my OLED module won't start up once out of ten or twenty times.
I have no clue why.
I change OLED modules (I have five and do all the same), changes breadboards, changed µC... I don't know what to try next.
Any idea?
Code:' OLED-72x40_16F18446
' ====== FUSES =====================================================================================
' External oscillator
#CONFIG
__config _CONFIG1, _FCMEN_OFF & _CSWEN_OFF & _CLKOUTEN_OFF & _RSTOSC_EXT1X & _FEXTOSC_HS
__config _CONFIG2, _MCLRE_OFF & _PWRTS_PWRT_64 & _LPBOREN_OFF & _BOREN_OFF & _BORV_LO & _ZCD_OFF & _PPS1WAY_OFF
__config _CONFIG3, _WDTCPS_WDTCPS_31 & _WDTE_SWDTEN & _WDTCWS_WDTCWS_7 & _WDTCCS_LFINTOSC
__config _CONFIG4, _BBSIZE_BB512 & _BBEN_OFF & _SAFEN_OFF & _WRTAPP_OFF & _WRTB_OFF & _WRTC_OFF & _WRTD_OFF & _WRTSAF_OFF & _LVP_OFF
__config _CONFIG5, _CP_OFF
#ENDCONFIG
@ ERRORLEVEL -306
@ ERRORLEVEL -202
' ====== REGISTERS =================================================================================
ANSELB = %00000000
' ====== DEFINES ===================================================================================
DEFINE OSC 32
DEFINE NO_CLRWDT 1 ' don't waste cycles clearing WDT
DEFINE HSER_CLOERR 1 ' automatic clear overrun error
DEFINE I2C_SLOW 1 ' if >8MHz
' ====== VARIABLES =================================================================================
SDA VAR PORTB.5 ' I2C Clock
SCL VAR PORTB.6 ' I2C Data
' SSD1306 OLED 72x40 module (has built-in 10k pull-up on SDA/SCL)
I2CDevice CON $78
Page VAR BYTE ' OLED's Pages 0..4
' ====== SSD1306 I2C OLED initialization ===========================================================
PAUSE 500 ' let display settle
' Initializing command set
I2CWrite SDA,SCL,I2CDevice,[$00,$AE,$D5,$80,$A8,$3F,$D3,$00,$20,$00,$AD,$30,$8D,$14,$68,$A6,$A4,_
$A1,$C8,$DA,$12,$81,$7F,$D9,$22,$DB,$40,$2E,$AF]
PAUSEUS 50
' ====== PROGRAM STARTUP ===========================================================================
STARTUP:
Gosub CLEAR_DISPLAY_FULL
' ====== MAIN PROGRAM ==============================================================================
MAIN:
GOSUB SPLASH1
PAUSE 2000
GOSUB SPLASH2
PAUSE 2000
GOTO MAIN
END
' ====== CLEAR FULL DISPLAY ROUTINE ================================================================
CLEAR_DISPLAY_FULL:
I2CWrite SDA,SCL,I2CDevice,[$00,$21,28,99,$22,0,4]
FOR Page = 0 TO 4
I2CWrite SDA,SCL,I2CDevice,[$40,_
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, _
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, _
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, _
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
NEXT Page
RETURN
' ====== SPLASH SCREEN DISPLAY =====================================================================
SPLASH1:
I2CWrite SDA,SCL,I2CDevice,[$40,_
0,0,252,252,252,60,28,28,28,56,248,248,240,192,0,0,0,252,252,252,0,0,0,0,192,240,248,120,60,28,28,28,28,60,248,248,240,192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
I2CWrite SDA,SCL,I2CDevice,[$40,_
0,0,255,255,255,56,56,56,56,60,31,31,15,3,0,0,0,255,255,255,0,0,0,62,255,255,255,128,0,0,0,0,0,0,192,192,192,192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
I2CWrite SDA,SCL,I2CDevice,[$40,_
0,0,15,15,15,0,0,0,0,0,0,0,0,0,0,0,0,15,15,15,0,0,0,0,1,3,7,15,14,14,12,14,14,15,15,7,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
I2CWrite SDA,SCL,I2CDevice,[$40,_
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,240,252,252,140,140,204,252,120,0,0,0,96,96,32,32,224,224,0,0,192,224,224,32,32,96,64,0,0,192,236,108,0,128,192,224,96,32,96,96,64,0]
I2CWrite SDA,SCL,I2CDevice,[$40,_
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,62,63,55,49,49,57,31,31,6,0,28,62,54,34,18,63,63,7,0,16,56,49,35,55,62,30,0,0,56,63,15,0,0,31,63,48,48,48,56,24,0,0]
RETURN
SPLASH2:
I2CWrite SDA,SCL,I2CDevice,[$40,_
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
I2CWrite SDA,SCL,I2CDevice,[$40,_
0,0,128,128,192,192,0,0,0,0,128,192,192,192,192,192,128,0,0,192,192,192,192,192,192,0,0,128,128,192,192,0,0,0,0,128,192,64,192,128,0,0,0,0,0,0,0,192,192,192,0,0,0,0,0,0,0,192,192,192,0,0,0,128,192,192,192,192,192,128,0,0]
I2CWrite SDA,SCL,I2CDevice,[$40,_
0,0,1,129,255,255,128,0,0,0,255,255,136,12,140,249,249,0,0,255,255,12,12,12,12,0,0,1,129,255,255,128,0,0,99,255,32,8,156,255,99,0,0,96,120,124,103,99,255,255,96,0,0,96,120,124,103,99,255,255,96,0,0,255,255,136,12,140,249,249,0,0]
I2CWrite SDA,SCL,I2CDevice,[$40,_
0,0,1,1,1,1,1,1,0,0,0,1,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,1,1,0,0,0]
I2CWrite SDA,SCL,I2CDevice,[$40,_
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
RETURN
Use a logical analyzer to see if the module responds to "Initializing command set" when it fails. If it doesn't respond you can try a longer pause "PAUSE 500 ' let display settle".
Check that you don't have any noise in the power lines or control lines.
How would I do this?
BTW, I just noticed that the module won't start up again if the time between a shut off and switch on is below 2-3 secs. Anyway, it is strange.
So, if I leave the module unpowered for more than 5 seconds, it'll always restart.
Maybe this is something absolutely "normal".
Hi, flotul,
did you try to send the initialization sequence twice in a row ???
I read in I-do-not remember-wich-datasheet to do that with some LCDs ...
BTW some oleds are really slow to init, did you try more than 500ms ???
Alain
Connect a logical analyzer to tx and rx. They are not expensive. Digikey has one for $20. You can see the ones and zeroes going to the module and coming back to the pic. If you don't use a logic analyzer, it is like shooting in the dark.
About that 2-3 seconds observation, it is very likely that it is a power issue. Maybe you have a large cap that is holding a charge.
https://www.digikey.com/en/products/...DgGxgOwgF0BfIA
Okay. Maybe the one from the PICKit Logic Tool may do the trick.
Attachment 9882
I'll give it a try but I'm quite sure there must be something with the modules themselves.
Thanks :wink:
I use a Saleae analyzer with 16 channels. It makes my life a lot easier.
Attachment 9883
Thanks. Should have asked Santa a few days ago :biggrin:
Anyway, this might clearly be on my list of tools to acquire.
Since the module you are using has no provision made for the user to be able to reset it you are totally dependent on how the on board POR circuitry applies the reset signal. The board will have a very definite absolute minimum off period and minimum on time before a successful reset will occur. If you don't adhere to those times then its matters not what you code is trying to do the chip won't necessarily be receptive. If your code still does not work reliably after suitable POR conditions have been met then you code is incorrect. Simply resetting your pic is not enough.Quote:
For any reason, my OLED module won't start up once out of ten or twenty times.
I have no clue why.
The data sheet gives no clue re command execution time or even if i2c clock stretching is in play, anecdotally there is some support for a small delay after executing an $ae command being beneficial