SSD1306 OLED (72x40) I2C display from scratch


+ Reply to Thread
Results 1 to 40 of 61

Hybrid View

  1. #1
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french speaking)
    Posts
    891

    Default SSD1306 OLED (72x40) I2C display from scratch

    Hi there,

    I juste received a bunch of very small (72x40) OLED displays driven by a SSD1306 controller.

    Name:  2023-11-13 17_51_05-Mini OLED 72x40 front_200x200.png
Views: 486
Size:  42.6 KBName:  2023-11-13 17_51_51-Mini OLED 72x40 back_200x200.png
Views: 476
Size:  53.3 KB

    I have absolutely never used those displays, in particular the SSD1306 controller.

    After a few searches in the forum, I got some examples but these don't really help unless I first understand the very basics.

    So, would anyone of you have a code snippet I could start with and ready to share it or a good reference to understand the SSD1306 please?

    For example, it starts right at the beginning: there seems to be a "display" address. Is this standard for I2C displays or should I get it from the manufacturer?

    Voilą, that's the low I'm right now...

    So again, if somenone has basic stuff to share, I would really appreciate
    Roger

  2. #2
    Join Date
    May 2013
    Location
    australia
    Posts
    2,368


    Did you find this post helpful? Yes | No

    Default Re: SSD1306 OLED (42x40) I2C display from scratch

    I got some examples but these don't really help unless I first understand the very basics.
    i would initialize the display as per my posts to start with and work from there


    there seems to be a "display" address. Is this standard for I2C displays or should I get it from the manufacturer?
    a simple i2c scan such as this will reveal the address

    Code:
    '****************************************************************'*  Name    : UNTITLED.BAS                                      *
    '*  Author  : [select VIEW...EDITOR OPTIONS]                    *
    '*  Notice  : Copyright (c) 2014 [select VIEW...EDITOR OPTIONS] *
    '*          : All Rights Reserved                               *
    '*  Date    : 9/23/2014                                         *
    '*  Version : 1.0                                               *
    '*  Notes   : pic16f1825                                        *
    '*          :  scan i2c bus                                     *
    '****************************************************************
                                
    #CONFIG
       __config _CONFIG1, _WDTE_ON    & _FOSC_INTOSC   &_MCLRE_ON    &_PWRTE_ON 
       __config _CONFIG2,              _LVP_OFF   & _PLLEN_ON
    #ENDCONFIG
             DEFINE OSC 32
             
      DEFINE I2C_SLOW 1
      
         osccon=$70    '8 mhz
             anselA=0        'dig i/o 
             ANSELC=0
          TRISC= %11111111
           TRISA= %11111110
           
      
    
    
    SCL                 var Portc.1                     ' I2C Clock  PortA.3
    SDA                 var Portc.0                     ' I2C Data   PortA.2
    
    
    
    
    
    
    
    
    
    
    
    
    I                   VAR BYTE
    
    
    buff                var byte[10]   
    addr                var byte
    
    
        porta.0=1
        DEFINE DEBUG_REG PORTA
        DEFINE DEBUG_BIT 0      ;  
        DEFINE DEBUG_BAUD 38400
        DEFINE DEBUG_MODE 0     
        pause 2000
        Debug "Start",13 ,10
    
    
    
    
    
    
    addr=$E3
    
    
    
    
    
    
    
    
    for I = $02 to $fe step 2
    I2Cwrite SDA,SCL,i,addr,[0],nak 
    ARRAYWRITE buff[1], [ "found",0]
    Debug str buff , 9  
    Debug "ack ",hex2 i , 13,10
    
    
    nak:
    
    
    Next I
    
    
    
    
    end
    Warning I'm not a teacher

  3. #3
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french speaking)
    Posts
    891


    Did you find this post helpful? Yes | No

    Default Re: SSD1306 OLED (42x40) I2C display from scratch

    okay, first step done!

    Name:  2023-11-14 17_59_52-Clipboard.png
Views: 423
Size:  13.5 KB
    Roger

  4. #4
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french speaking)
    Posts
    891


    Did you find this post helpful? Yes | No

    Default Re: SSD1306 OLED (42x40) I2C display from scratch

    Richard,

    I'm not sure to find your initialisation example.

    I found the one from Tim (https://www.picbasic.co.uk/forum/sho...nclude-example).

    I'll try this one if it is okay.
    Roger

  5. #5
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,766


    Did you find this post helpful? Yes | No

    Default Re: SSD1306 OLED (42x40) I2C display from scratch


  6. #6
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french speaking)
    Posts
    891


    Did you find this post helpful? Yes | No

    Default SSD1306 OLED (72x40) I2C display from scratch

    Thanks Ioannis.

    I saw them all but there are many files and includes (...) that Tim's example seemed "easier" to start with.

    Not knowing what I really need to keep among them for a start, it's a little bit more confusing.

    I need help so I'll go back to the post you mentionned and (try to) compose/compile what I need to run on a 16F
    Roger

  7. #7
    Join Date
    May 2013
    Location
    australia
    Posts
    2,368


    Did you find this post helpful? Yes | No

    Default Re: SSD1306 OLED (42x40) I2C display from scratch

    Some comments
    is the display 72x40 of 42x40 ? you describe it both ways
    the write window should be set to width and page height you require and the pixel/page offset to begin write from for proper operation

    and

    with your attempted title page transmission, sending every byte of data like that as individual senddata transactions is extremely inefficient the entire thing could be sent as a single data block in half the time



    Code:
     ====== DESCRIPTION ===============================================================================' Use mini OLED 72x40 pixel display
    
    
    ' ====== FUSES =====================================================================================
    ' PIC 16F690 Fuses
    ' Internal oscillator  (activate OSCCON register)
    @ __config _FCMEN_OFF &_IESO_OFF &_CPD_OFF &_WDT_OFF &_INTRC_OSC_NOCLKOUT &_BOR_OFF &_CP_OFF &_PWRTE_OFF &_MCLRE_OFF
    
    
    @ ERRORLEVEL -306
    @ ERRORLEVEL -202
    
    
    ' ====== REGISTERS =================================================================================
    '             76543210
    OPTION_REG = 000000 'PORT A&B Pull-Ups disabled (see WPUA & WPUB)
    OSCCON     = 100000 'Internal RC set to 4MHZ
    'ANSEL      = 000000 'Select analog inputs Channels 0 to 7 (AN2 + AN4 selected)
    'ANSELH     = 000000 'Select analog inputs Channels 8 to 11
    'ADCON0     = 000000 'A/D Module (Bit5:2 select channels 0:11)
    'ADCON1     = 000000 'A/D control register
    'CM1CON0    = 000000 'Comparator1 Module is OFF
    'CM2CON0    = 000000 'Comparator2 Module is OFF
    'INTCON     = 000000 'INTerrupts CONtrol (TMR0 OFF)
    'TRISA      = 000000 'Set Input/Output (0 to 5)
    'PORTA      = 000000 'Ports High/Low (0 to 5)
    'TRISB      = 000000 'Set Input/Output (4 to 7)
    'PORTB      = 000000 'Ports High/Low (4 to 7)
    'TRISC      = 000000 'Set Input/Output (0 to 7)
    'PORTC      = 000000 'Ports High/Low (0 to 7)
    
    
    ' ====== DEFINES ===================================================================================
    DEFINE OSC 4
    'DEFINE NO_CLRWDT 1   'Don't waste cycles clearing WDT  
    'DEFINE HSER_CLOERR 1 'Automatic clear overrun error 
    
    
    ' ====== VARIABLES =================================================================================
    I2CDevice   var byte
    
    
    SDA         VAR PORTB.4 ' I2C Data
    SCL         VAR PORTB.6 ' I2C Clock
    
    
    TEXT        VAR BYTE[20]
    LENGTH      VAR BYTE[2]
    DC          VAR Byte    ' "DATA OR COMMAND", $40=DATA; $0=COMMAND --> changed from bit to byte
    ;seems a pointless waste if a variable
    LCD_DATA    VAR BYTE   
    COM         VAR BYTE    ' COMMAND
    
    
    I           VAR BYTE
    J           VAR BYTE
    X           VAR BYTE  'LCD POSITION X(0 TO 127)
    Y           VAR BYTE  'LCD POSITION Y(0 TO 7)
    
    
    ' ====== INITIALIZE VARIABLES ======================================================================
    I2CDevice = $78
    
    
    '======= 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 = $80 : 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 ' not offset
    COM = $AD : GOSUB SEND_COMMAND ' Internal IREF Setting    
    COM = $30 : GOSUB SEND_COMMAND ' --
    COM = $8D : GOSUB SEND_COMMAND ' set Charge Pump enable/disable
    COM = $14 : GOSUB SEND_COMMAND ' set(0x10) disable
    COM = $40 : GOSUB SEND_COMMAND ' set start line address
    COM = $A6 : GOSUB SEND_COMMAND ' set normal display
    ; you assume display is mapped from page 0  , this may not be correct ans could be  0,1,2,3
    
    
    COM = $A4 : GOSUB SEND_COMMAND ' Disable Entire Display On
    COM = $A1 : GOSUB SEND_COMMAND ' set segment re-map 128 to 0
    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 '
    COM = $81 : GOSUB SEND_COMMAND ' set contrast control register
    COM = $AF : GOSUB SEND_COMMAND ' 
    COM = $D9 : GOSUB SEND_COMMAND ' set pre-charge period
    COM = $22 : GOSUB SEND_COMMAND '
    COM = $DB : GOSUB SEND_COMMAND ' set vcomh
    COM = $20 : GOSUB SEND_COMMAND ' 
    COM = $AF : GOSUB SEND_COMMAND ' turn on oled panel    
    
    
    ' ====== PROGRAM ===================================================================================
    PAUSE 20
    GOSUB CLEAR_LCD
    GOSUB TITLE
    
    
    MAIN:
        PAUSE 1000
        GOTO MAIN
    END
    
    
    ' ====== CLEAR LCD =================================================================================
    CLEAR_LCD:
        FOR J = 0 TO 7 
            FOR I = 0 TO 71 '127
                LCD_DATA = $00 : GOSUB SEND_DATA
            NEXT I
        NEXT J                             
        RETURN 
    ;  cant see this working without setting a "window" to write into properly
        
    ' ====== SEND COMMAND ==============================================================================
    SEND_COMMAND:
        dc = $0
        I2CWrite SDA,SCL,I2CDevice,DC,[COM]
        dc = $40
        RETURN 
    
    ; why not just
    SEND_COMMAND:
    I2CWrite SDA,SCL,I2CDevice,[0,COM]
       RETURN  
    
     
    ' ====== CLEAR LCD =================================================================================
    SEND_DATA:
        DC = $40
        I2CWrite SDA,SCL,I2CDevice,DC,[LCD_DATA]
        RETURN
     ; why not just
    SEND_COMMAND:
    I2CWrite SDA,SCL,I2CDevice,[$40,LCD_DATA]
       RETURN   
    ' ====== SEND DATA =================================================================================
    FILL:
        FOR J = 0 TO 7
            FOR I = 0 TO 71 '127
                LCD_DATA = $FF : GOSUB SEND_DATA
            NEXT I
        NEXT J
        RETURN
     ;  cant see this working without setting a "window" to write into properly  
    ' ====== TITLE =====================================================================================
    ;here you set 6 pages "Y" of data from page 0 to 7  with page 2 missing when a 40 pixel height can have 5 pages maximum
    
    TITLE:
        X = 0 : Y = 0 : GOSUB SET_XY
        FOR I = 0 TO 71 '127
            LOOKUP I,[$00,$40,$60,$50,$7E,$50,$60,$40,$02,$06,$0E,$1E,$3E,$00,$00,$00,_
            $00,$00,$00,$00,$00,$1F,$3F,$60,$60,$60,$60,$60,$60,$3C,$1C,$00,_
            $00,$7F,$7F,$61,$61,$61,$61,$61,$61,$3F,$1E,$00,$00,$1E,$3F,$61,_
            $61,$61,$61,$61,$61,$38,$18,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
            $00,$00,$00,$00,$00,$00,$00,$1F,$3F,$60,$60,$60,$60,$60,$60,$3C,_
            $1C,$00,$00,$1E,$3F,$61,$61,$61,$61,$61,$61,$38,$18,$00,$00,$3F,_
            $7F,$60,$18,$06,$06,$18,$60,$7F,$3F,$00,$00,$00,$00,$00,$00,$00,_
            $00,$00,$00,$1C,$63,$41,$5D,$41,$5D,$41,$5D,$41,$5D,$41,$7F,$00],LCD_DATA
            lcd_data = lcd_data rev 8
            GOSUB SEND_DATA
        NEXT I
    
    
        X = 0 : Y = 1 : GOSUB SET_XY
        for i = 0 to 71 '127
            lookup i,[$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
            $00,$00,$00,$00,$00,$F8,$FC,$06,$06,$06,$C6,$C6,$C6,$FC,$F8,$00,_
            $00,$FE,$FE,$80,$80,$80,$80,$80,$80,$00,$00,$00,$00,$18,$1C,$86,_
            $86,$86,$86,$86,$86,$FC,$78,$00,$00,$00,$00,$00,$00,$00,$00,$00,_
            $00,$00,$00,$00,$00,$00,$00,$F8,$FC,$06,$06,$06,$C6,$C6,$C6,$FC,_
            $F8,$00,$00,$18,$1C,$86,$86,$86,$86,$86,$86,$FC,$78,$00,$00,$FE,_
            $FE,$00,$00,$00,$00,$00,$00,$FE,$FE,$00,$00,$00,$00,$00,$00,$00,_
            $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00],lcd_data
            lcd_data=lcd_data rev 8
            GOSUB SEND_DATA
        NEXT I
    
    
        X = 0 : Y = 3 : GOSUB SET_XY
        for i = 0 to 71 '127
            lookup i,[$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$3C,$7E,$C3,$C3,$C3,$C3,_
            $C3,$C3,$71,$30,$00,$00,$7F,$FF,$C3,$C3,$C3,$C3,$C3,$C3,$C3,$C3,_
            $00,$00,$7F,$FF,$C1,$C1,$C1,$C1,$C1,$C1,$FF,$7F,$00,$00,$7F,$FF,_
            $C3,$C3,$C3,$C3,$C3,$C3,$7E,$3C,$00,$00,$3F,$7F,$C0,$C0,$C0,$C0,_
            $C0,$C0,$70,$30,$00,$00,$FF,$FF,$03,$03,$03,$03,$03,$03,$FF,$FF,_
            $00,$00,$C0,$C0,$C0,$C0,$FF,$FF,$C0,$C0,$C0,$C0,$00,$00,$FF,$FF,_
            $0C,$0C,$03,$03,$00,$00,$FF,$FF,$00,$00,$3F,$7F,$C0,$C0,$C0,$C1,_
            $C1,$C1,$79,$39,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00],lcd_data
            lcd_data=lcd_data rev 8
            GOSUB SEND_DATA
        NEXT I
    
    
        X = 0 : Y = 4 : GOSUB SET_XY
        for i = 0 to 71 '127
            lookup i,[$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$30,$38,$0C,$0C,$0C,$0C,_
            $0C,$0C,$F8,$F0,$00,$00,$F8,$FC,$0C,$0C,$0C,$0C,$0C,$0C,$0C,$0C,_
            $00,$00,$FC,$FC,$80,$80,$80,$80,$80,$80,$FC,$FC,$00,$00,$FC,$FC,_
            $80,$C0,$60,$30,$18,$0C,$04,$00,$00,$00,$F0,$F8,$0C,$0C,$0C,$0C,_
            $0C,$0C,$38,$30,$00,$00,$FC,$FC,$00,$00,$00,$00,$00,$00,$FC,$FC,_
            $00,$00,$0C,$0C,$0C,$0C,$FC,$FC,$0C,$0C,$0C,$0C,$00,$00,$FC,$FC,_
            $00,$00,$00,$00,$C0,$C0,$FC,$FC,$00,$00,$F0,$F8,$0C,$0C,$0C,$8C,_
            $8C,$8C,$F8,$F0,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00],lcd_data
            lcd_data=lcd_data rev 8
            GOSUB SEND_DATA
        NEXT I
    
    
        X = 0 : Y = 5 : GOSUB SET_XY
        for i = 0 to 71 '127
            lookup i,[$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$1F,$3F,$30,$30,$30,$30,_
            $30,$30,$30,$30,$00,$00,$0F,$1F,$30,$30,$30,$30,$30,$30,$1F,$0F,_
            $00,$00,$1F,$3F,$30,$30,$30,$30,$30,$30,$1F,$0F,$00,$00,$00,$00,_
            $00,$00,$00,$0F,$1F,$30,$30,$30,$30,$30,$30,$1C,$0C,$00,$00,$30,_
            $30,$30,$30,$3F,$3F,$30,$30,$30,$30,$00,$00,$0F,$1F,$30,$30,$30,_
            $30,$30,$30,$1E,$0E,$00,$00,$3F,$3F,$03,$03,$00,$00,$00,$00,$3F,_
            $3F,$00,$00,$1F,$3F,$30,$30,$30,$30,$30,$30,$3F,$1F,$00,$00,$3F,_
            $3F,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00],lcd_data
            lcd_data=lcd_data rev 8
            GOSUB SEND_DATA
        NEXT I
    
    
        X = 0 : Y = 6 : GOSUB SET_XY
        for i = 0 to 71 '127
            lookup i,[$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$FF,$FF,$C0,$C0,$C0,$C0,_
            $C0,$C0,$00,$00,$00,$00,$FC,$FE,$03,$03,$03,$03,$03,$03,$FE,$FC,_
            $00,$00,$FF,$FF,$E0,$F0,$D8,$CC,$C6,$C3,$81,$00,$00,$00,$00,$00,_
            $00,$00,$00,$0C,$8E,$C3,$C3,$C3,$C3,$C3,$C3,$7E,$3C,$00,$00,$03,_
            $03,$03,$03,$FF,$FF,$03,$03,$03,$03,$00,$00,$FC,$FE,$03,$03,$03,_
            $63,$63,$63,$7E,$7C,$00,$00,$FF,$FF,$00,$00,$C0,$C0,$30,$30,$FF,_
            $FF,$00,$00,$FF,$FF,$60,$60,$60,$60,$60,$60,$FF,$FF,$00,$00,$FF,_
            $FF,$03,$03,$03,$03,$03,$03,$03,$03,$00,$00,$00,$00,$00,$00,$00],lcd_data
            lcd_data=lcd_data rev 8
            GOSUB SEND_DATA
        NEXT I
        RETURN
        
    '======= SET_XY ====================================================================================
    SET_XY:
        COM = $21 : GOSUB SEND_COMMAND
        COM = X   : GOSUB SEND_COMMAND
        COM = 71  : GOSUB SEND_COMMAND
        COM = $22 : GOSUB SEND_COMMAND
        COM = Y   : GOSUB SEND_COMMAND
        COM = 41  : GOSUB SEND_COMMAND
    ;attempt to set page to 41 when it cannot be > than 5 pages
    
    
        RETURN
    Last edited by richard; - 20th November 2023 at 00:53.
    Warning I'm not a teacher

  8. #8
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french speaking)
    Posts
    891


    Did you find this post helpful? Yes | No

    Default SSD1306 OLED (72x40) I2C display from scratch

    It's definitively a 72x40 pixel display.

    Thanks Richard for pointing to all changes (and tips) I can/should make in the code

    Now, regarding the way to display data, I still don't get it; I'm completely lost since I have no clue how to do it.

    I'm mostly using serial "common" LCDs in text mode so I don't have to create any font or so.

    In my case, I will use this LCD to display, as big as possible, a number as a percentage (0.0%...99.9%).

    What is the approach? I have a display 72 pixels wide and 40 pixels high (= 2'880 pixels). I assume, the display is divided in what they call "pages" and I should write a data table (LOOKUP) for each page. Is this correct?

    But how do I address the pages? Do I have to do so? Is there a way to send "text" to the display like common LCDs? Is there a way to "design" a font that will in big appear all over the entire display?

    I'm missing fundamentals 😔
    Roger

  9. #9
    Join Date
    May 2013
    Location
    australia
    Posts
    2,368


    Did you find this post helpful? Yes | No

    Default Re: SSD1306 OLED (42x40) I2C display from scratch

    Basically the display is 360 bytes of ram where every bit is a oled, the ram is divided into 5 pages each of 72 bytes
    the 5 pages are overlaid onto a larger array that is 8 pages of 128 bytes, precisely where is not known to me [i have never seen one of those modules]
    the ssd1306 is very versatile and allows vertical and horiz offsets to be set along with scan direction and various mem access methods to suit you.
    to write to a byte you must address its x and y position , the width to be written and number of pages is also expected to be set

    ie to write a 10x14 chr 14 high 10 wide at page 1 posn 12

    SET_XY:
    COM = $21 : GOSUB SEND_COMMAND
    COM = 12 : GOSUB SEND_COMMAND ;x=12
    COM = 22 : GOSUB SEND_COMMAND ;12+10
    COM = $22 : GOSUB SEND_COMMAND
    COM = 1 : GOSUB SEND_COMMAND ;y=1
    COM = 2 : GOSUB SEND_COMMAND ;1+1
    RETURN
    then send the 20 bytes needed to represent your chr


    In my case, I will use this LCD to display, as big as possible, a number as a percentage (0.0%...99.9%).
    easy you need to create a big font with the chrs you need in it


    Is there a way to send "text" to the display like common LCDs?
    no not even close

    if you want easy use a pic18 and my code from here

    where you can define the screen size and create fonts as you need

    or use an enhanced core pic16 and my earlier code that can do double size chrs
    Last edited by richard; - 20th November 2023 at 10:28.
    Warning I'm not a teacher

  10. #10
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french speaking)
    Posts
    891


    Did you find this post helpful? Yes | No

    Default SSD1306 OLED (72x40) I2C display from scratch

    Thanks a lot Richard.

    The fog lifts somehow a little bit....

    I'll give it a try with y 18F 👍
    Last edited by flotulopex; - 20th November 2023 at 10:36.
    Roger

  11. #11
    Join Date
    May 2013
    Location
    australia
    Posts
    2,368


    Did you find this post helpful? Yes | No

    Default Re: SSD1306 OLED (42x40) I2C display from scratch

    is this more clear ?
    draws a 7x5 chr A and 14x10 A in a 72x40 window located @ x=0y=0 after clearing screen [ outside of window is just random noise ]

    here's a pic on a 128x64 screen , there is no telling how it line up for your screen
    Name:  sd1306.jpg
Views: 345
Size:  512.8 KB






    #CONFIG __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOD_ON & _IESO_ON & _FCMEN_ON
    #ENDCONFIG




    define OSC 8




    OSCCON = 110000 'Internal RC set to 8MHZ
    'ANSEL = 000000 'Select analog inputs Channels 0 to 7 (AN2 + AN4 selected)
    'ANSELH = 000000 'Select analog inputs Channels 8 to 11


    'TRISB = 000000 'Set Input/Output (4 to 7)
    'PORTB = 000000 'Ports High/Low (4 to 7)








    ' ====== VARIABLES ================================================== ===============================
    I2CDevice var byte


    SDA VAR PORTB.6 ' I2C Data
    SCL VAR PORTB.4 ' I2C Clock






    LCD_DATA VAR BYTE
    COM VAR BYTE ' COMMAND


    I VAR BYTE
    J VAR BYTE
    X VAR BYTE 'LCD POSITION X(0 TO 127)
    Y VAR BYTE 'LCD POSITION Y(0 TO 7)


    ' ====== INITIALIZE VARIABLES ================================================== ====================
    I2CDevice = $78


    '======= 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 = $80 : GOSUB SEND_COMMAND ' set divide ratio
    COM = $A8 : GOSUB SEND_COMMAND ' set multiplex ratio
    COM = $3F : GOSUB SEND_COMMAND ' 1/40 duty
    COM = $D3 : GOSUB SEND_COMMAND ' set display offset
    COM = $0 : GOSUB SEND_COMMAND
    COM = $20 : GOSUB SEND_COMMAND
    COM = $0 : GOSUB SEND_COMMAND
    COM = $AD : GOSUB SEND_COMMAND ' Internal IREF Setting
    COM = $30 : GOSUB SEND_COMMAND ' --
    COM = $8D : GOSUB SEND_COMMAND ' set Charge Pump enable/disable
    COM = $14 : GOSUB SEND_COMMAND ' set(0x10) disable
    COM = $40 : GOSUB SEND_COMMAND ' set start line address
    COM = $A6 : GOSUB SEND_COMMAND ' set normal display
    COM = $A4 : GOSUB SEND_COMMAND ' Disable Entire Display On
    COM = $A1 : GOSUB SEND_COMMAND ' set segment re-map 128 to 0
    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 '
    COM = $81 : GOSUB SEND_COMMAND ' set contrast control register
    COM = $7F : GOSUB SEND_COMMAND '
    COM = $D9 : GOSUB SEND_COMMAND ' set pre-charge period
    COM = $22 : GOSUB SEND_COMMAND '
    COM = $DB : GOSUB SEND_COMMAND ' set vcomh
    COM = $40 : GOSUB SEND_COMMAND '
    COM = $AF : GOSUB SEND_COMMAND ' turn on oled panel


    ' ====== PROGRAM ================================================== =================================


    GOSUB CLEAR_LCD


    MAIN:
    ;7x5 "A"
    X = 15 : Y = 0 : GOSUB SET_7
    I2CWrite SDA,SCL,I2CDevice,[$40,$fc,$12,$12,$12,$fc]
    ;14x10 "A"
    X = 15 : Y = 2 : GOSUB SET_14
    I2CWrite SDA,SCL,I2CDevice,[$40,$f0,$f8,12,12,14,14,12,12,$f8,$f0_
    ,$ff,$ff,6,6,6,6,6,6,$ff,$ff]
    PAUSE 1000
    GOTO MAIN
    END


    ' ====== CLEAR LCD ================================================== ===============================
    CLEAR_LCD:
    COM = $21 : GOSUB SEND_COMMAND
    COM = 0 : GOSUB SEND_COMMAND
    COM = 71 : GOSUB SEND_COMMAND
    COM = $22 : GOSUB SEND_COMMAND
    COM = 0 : GOSUB SEND_COMMAND
    COM = 4 : GOSUB SEND_COMMAND
    LCD_DATA = $00
    FOR J = 0 TO 4
    FOR I = 0 TO 71
    I2CWrite SDA,SCL,I2CDevice,[$40,LCD_DATA]
    NEXT I
    NEXT J
    RETURN

    ' ====== SEND COMMAND ================================================== ============================
    SEND_COMMAND:
    I2CWrite SDA,SCL,I2CDevice,[0,COM]
    RETURN



    '======= SET_XY ================================================== ==================================
    SET_7: '7x5
    COM = $21 : GOSUB SEND_COMMAND
    COM = X : GOSUB SEND_COMMAND
    COM = x+4 : GOSUB SEND_COMMAND
    COM = $22 : GOSUB SEND_COMMAND
    COM = Y : GOSUB SEND_COMMAND
    COM = y : GOSUB SEND_COMMAND
    RETURN
    SET_14: ;14x10
    COM = $21 : GOSUB SEND_COMMAND
    COM = X : GOSUB SEND_COMMAND
    COM = x+9 : GOSUB SEND_COMMAND
    COM = $22 : GOSUB SEND_COMMAND
    COM = Y : GOSUB SEND_COMMAND
    COM = y+1 : GOSUB SEND_COMMAND
    RETURN
    Last edited by richard; - 22nd November 2023 at 03:14.
    Warning I'm not a teacher

  12. #12
    Join Date
    May 2013
    Location
    australia
    Posts
    2,368


    Did you find this post helpful? Yes | No

    Default Re: SSD1306 OLED (42x40) I2C display from scratch

    link worked.


    all you need to do now is
    1 create a 14x10 font with the chrs you need
    2 workout an efficient way to store and retrieve the font
    3 develop a nice way to plonk it on the screen

    easy as pie
    ps
    if you only need numbers and "%" ,"." it could fit on a 16f690 easily




    hint , pic16 flash memory is 14 bits wide, the ssd1306 can fill memory in vertical mode too
    Last edited by richard; - 25th November 2023 at 00:15.
    Warning I'm not a teacher

  13. #13
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french speaking)
    Posts
    891


    Did you find this post helpful? Yes | No

    Default Re: SSD1306 OLED (42x40) I2C display from scratch

    Thank you so much Richard!!!

    I'll give it a try to create a super big font.

    Let you know for any progress in the next days
    Roger

  14. #14
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french speaking)
    Posts
    891


    Did you find this post helpful? Yes | No

    Default Re: SSD1306 OLED (72x40) I2C display from scratch

    First look at what it could look like

    Name:  000.png
Views: 270
Size:  370.0 KB
    Roger

  15. #15
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,766


    Did you find this post helpful? Yes | No

    Default Re: SSD1306 OLED (42x40) I2C display from scratch

    It looks great!

    Well done Roger!

    Ioannis

  16. #16
    Join Date
    Aug 2006
    Location
    SWITZERLAND (french speaking)
    Posts
    891


    Did you find this post helpful? Yes | No

    Default Re: SSD1306 OLED (42x40) I2C display from scratch

    ...credits are all for Richard
    Roger

Similar Threads

  1. big char oled display
    By mombasa in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 19th September 2020, 08:02
  2. SSD1306 start display problem
    By harryweb in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 14th December 2016, 20:16
  3. Cannot drive I2C Oled :(
    By elcrcp in forum mel PIC BASIC Pro
    Replies: 21
    Last Post: - 20th August 2016, 13:19
  4. OLED Display Noise problem
    By gunayburak in forum mel PIC BASIC Pro
    Replies: 24
    Last Post: - 5th July 2016, 11:15
  5. Help With OLED Display / 128X64 SSD1306
    By Denner in forum General
    Replies: 6
    Last Post: - 25th May 2013, 16:40

Members who have read this thread : 25

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts