Cannot drive I2C Oled :(


Closed Thread
Results 1 to 22 of 22

Hybrid View

  1. #1
    Join Date
    Feb 2013
    Posts
    1,137


    Did you find this post helpful? Yes | No

    Default Re: Cannot drive I2C Oled :(

    Using above code, I've tried to use this display with 16F870:

    http://www.ebay.com/itm/221727746237...%3AMEBIDX%3AIT

    But it does not works:

    Code:
    '****************************************************************
    '*  Name    : UNTITLED.BAS                                      *
    '*  Author  : [select VIEW...EDITOR OPTIONS]                    *
    '*  Notice  : Copyright (c) 2014 [select VIEW...EDITOR OPTIONS] *
    '*          : All Rights Reserved                               *
    '*  Date    : 07.02.2014                                        *
    '*  Version : 1.0                                               *
    '*  Notes   :                                                   *
    '*          :                                                   *
    '****************************************************************
    
    Include "modedefs.bas"  ' Include serial modes
       TRISA = %11111111       ' Set PORTA to all input
       TRISC = %00000000	    ' Sets all PortB pins to output
       ADCON1 = %10001001      ' Set PORTA analog and right justify result
       ADCON0=%00000000
       low portc.4
       low portc.5
    
    DEFINE LCD_DREG PORTB
    DEFINE LCD_DBIT 4
    DEFINE LCD_RSREG PORTB
    DEFINE LCD_RSBIT 0
    DEFINE LCD_EREG PORTB
    DEFINE LCD_EBIT 1
    DEFINE LCD_BITS 4 
    DEFINE LCD_LINES 2
    DEFINE LCD_COMMANDUS 1500
    DEFINE LCD_DATAUS 44
    DEFINE OSC 4
    
    '==========================MCU SETUP============================================  
    
    
    'DEFINE I2C_SLOW 1 'Used to work with 100KHz devicez when using over 4MHz (my screen working without this too)
    'DEFINE I2C_HOLD 1 'Holding Lines low when not sending data (not necessary)
    
    OPTION_REG=0
    ADCON0=0
    ADCON1=7
    TRISB=%00000001
    trisc = %11111111           'PortC 0, 1, 2 outputs
    PortC = %00110000           'scl & sda high to start
    
    
    led     var portC.0
    scl     var PortC.4
    sda     var PortC.5
    dat     var byte
    counter var word
    
    control con %01111000       'I2C slave address (write mode)
    
    pause 500
    
    
    
        pause 2000
        gosub RESET:
        gosub init_oled:
        i2cwrite sda,scl,control,[$78,$AF]  'Display ON
        pause 10
    
    Start:
    
        led = 1                             'Code running
        i2cwrite sda,scl,control,[$78,$A7]  'Inverse Display 
        pause 500
        i2cwrite sda,scl,control,[$78,$A6]  'Normal Display
        pause 20
    '    i2cwrite sda,scl,control,[$78,$21,$00,$40] 'Set columns
        pause 20
    '    i2cwrite sda,scl,control,[$78,$22,$00,$04]  'Set pages
        pause 500     
        for counter = 0 to 1023
        i2cwrite sda,scl,control,[$40,$FF]
        next
        led = 0                             'Code running
        for counter = 0 to 1023
    lcdout $fe,$C0, #counter, " main   "
        i2cwrite sda,scl,control,[$40,$00]
        next
    GOTO Start:
    
    INIT_OLED:
    lcdout $fe,$C0, "init   "
        i2cwrite sda,scl,control,[$78,$AE]          'Display OFF               ****
        pause 1
        i2cwrite sda,scl,control,[$78,$2E]          'Deactivate scrolling
        pause 1
        i2cwrite sda,scl,control,[$78,$20,$10]      'Page addressing mode      ****
        pause 1
        i2cwrite sda,scl,control,[$78,$A0]          '                          ****
    '    i2cwrite sda,scl,control,[$78,$A1]          '                          ****
        pause 1
        i2cwrite sda,scl,control,[$78,$A6]          'WHITE chars BLACK backround
    '    i2cwrite sda,scl,control,[$78,$A7]         'BLACK chars WHITE backround
        pause 1
        i2cwrite sda,scl,control,[$78,$81,$7F]      'Setup contrast            XXXX
        pause 1
        i2cwrite sda,scl,control,[$78,$AF]          'Display on                **** 
        pause 1
        i2cwrite sda,scl,control,[$78,$40]
        pause 1
    '    i2cwrite sda,scl,control,[$78,$C0]          'Flip display vertically   ****
        i2cwrite sda,scl,control,[$78,$C8]          'Flip display vertically   ****
        pause 1
    '    i2cwrite sda,scl,control,[$78,$A0]          '                          ****
        i2cwrite sda,scl,control,[$78,$A1]          '                          ****
        pause 1
        i2cwrite sda,scl,control,[$78,$00,$78,$10]  'Set column start address  ****
        pause 1
        i2cwrite sda,scl,control,[$78,$B0]          'Set page start address    ****
        pause 1
        return
        
    RESET:
        i2cwrite sda,scl,control,[$78,$AE]          'Display OFF
        pause 10
        I2Cwrite sda,scl,control,[$78,$20,$02]      'Page addressing mode
        pause 10
        i2cwrite sda,scl,control,[$78,$B0]          'Page start address
        pause 10
        i2cwrite sda,scl,control,[$78,$00,$78,$10]  'Set column start address
        pause 10
        i2cwrite sda,scl,control,[$78,$A0]          'Address 0 mapped to SEG 0
        pause 10
     '   i2cwrite sda,scl,control,[$78,$A1]          'Address 0 mapped to SEG 127
        pause 10
        i2cwrite sda,scl,control,[$78,$D3,$00]      'Display offset
        pause 10
    
        pause 10
        i2cwrite sda,scl,control,[$78,$40]          'Display start line
        Pause 10
        i2cwrite sda,scl,control,[$78,$C0]          'Output scan direction
        pause 10
        i2cwrite sda,scl,control,[$78,$A6]          'WHITE chars BLACK backround
        pause 10
        i2cwrite sda,scl,control,[$78,$81,$7F]      'Contrast control
        pause 10
        i2cwrite sda,scl,control,[$78,$A4]          'Entire display OFF
        pause 10
        i2cwrite sda,scl,control,[$78,$A6]          'Normal display
        pause 10
        i2cwrite sda,scl,control,[$78,$A3,$00,$40]  'Set vertical scroll
        pause 10
        i2cwrite sda,scl,control,[$78,$20,$00]      'Horizontal addressing mode
    '    i2cwrite sda,scl,control,[$78,$20,$01]      'Vertical addressing mode
        RETURN
    The initial address was $80, so I've changed it to $78, as shown on picture of the OLED itself.

  2. #2
    Join Date
    Apr 2013
    Posts
    32


    Did you find this post helpful? Yes | No

    Default Re: Cannot drive I2C Oled :(

    It is same oled I used. First of all, sending 00 and FF for seeing empty and full screen won't work try 00 and 0F. I think ssd1306 outputs are not able to drive all leds at same time. Secondly, your mcu setup is in a mess, you are setting trises and adcons 2 times and differently. Plus, you should set portc.4 and 5 as outputs since PIC is master here, you are setting them inputs in these codes. Both your RESET and INIT subroutines are actually INIT routunies, Sending wrong commands may interrupt oled's working, keep them simple and use only 1 INIT routine(you can use same routine as reset) You may use these codes as init.
    Code:
    '=========================lcd initialization====================================
    INIT:
    I2CWrite SDA,SCL,I2CDevice,[DC,$AE]'Display Off
    pause 10
    I2CWrite SDA,SCL,I2CDevice,[DC,$20,$10]' Page adressing mode
    I2CWrite SDA,SCL,I2CDevice,[DC,$D3,$00]' Set offset to 0
    I2CWrite SDA,SCL,I2CDevice,[DC,$40]' Set display start line 0
    I2CWrite SDA,SCL,I2CDevice,[DC,$81,$FF]' Set contrast to full
    I2CWrite SDA,SCL,I2CDevice,[DC,$A4]' display on continue 
    I2CWrite SDA,SCL,I2CDevice,[DC,$A6]' $A6=NORMAL MODE;$A7=INVERSE MODE
    I2CWrite SDA,SCL,I2CDevice,[DC,$A1]' set column 127 as start
    i2cwrite sda,scl,I2CDevice,[DC,$C8]'Flip display vertically ****
    'above 2 lines for arranging screen direction, deleting them will
    'turn the display direction 180 degree
    I2CWrite SDA,SCL,I2CDevice,[DC,$AF]'Display On
    pause 10
    '===============================================================================
    You don't need to send control commands in your main routine unless you want to really control the screen, delete them. Put some delay after sending 00 / 0f to screen,

    Aaannnd last of all, before entering my comment, I checked 16f870's datasheet for SDA SCL pins but I couldn't see I2C support in device specs. I don't know if you can use I2CWrite command with that model.

  3. #3
    Join Date
    Feb 2013
    Posts
    1,137


    Did you find this post helpful? Yes | No

    Default Re: Cannot drive I2C Oled :(

    Thanks, I will try with PIC16F876A, which has hardware I2C capabilities.

  4. #4
    Join Date
    Jan 2005
    Location
    Boston MA
    Posts
    19


    Did you find this post helpful? Yes | No

    Default Re: Cannot drive I2C Oled :(

    Been working on a new char table for the OLED. Problem is the LOOKUP command can only take 255 bytes. This new routine can replace the one from elcrcp above. I have added a few new variables:

    Code:
    'charset var byte 'Char codes index
    charset var word 'Char codes index
    chartmp var byte 'char codes index temp
    letter_temp var byte	' working copy
    Just change Find_Char to Find_Char2
    Code:
    '=============================Find Char  2=======================================
    Find_Char2:
    ' Enter this Subroutine with printable character: letter_reg
    ' letter_reg is subtracted from " " (space char) and * by 5 to be able to index into one table
    ' One table is broken into 3 to avoid the 255 max.  Index into table must be a byte variable.
    
    	letter_temp = letter_reg - 32	' Space is now at index 0 all other characters are 32 less into index
    	letter_temp = letter_temp * 5	' Every character is made of 5 bytes
        for charset=letter_temp to letter_temp+4
    	IF letter_reg < "A" then
    	chartmp = charset - 0 	' lookup variable must be 8 bits 
        lookup chartmp,[$00,$00,$00,$00,$00,$00,$00,$5F,$00,$00,$14,$7F,$14,$7F,$14,$00,$08,$07,$03,$00,_	'sp,!,#,"
    					$24,$2A,$7F,$2A,$12,$23,$13,$08,$64,$62,$36,$49,$56,$20,$50,_	'$,%,&
    					$00,$08,$07,$03,$00,$00,$1C,$22,$41,$00,$00,$41,$22,$1C,$00,_	'',(,)
    					$2A,$1C,$7F,$1C,$2A,$08,$08,$3E,$08,$08,$00,$00,$70,$30,$00,_	'*,+,,
    					$08,$08,$08,$08,$08,$00,$00,$60,$60,$00,$20,$10,$08,$04,$02,_	'-,.,/
    					$3E,$51,$49,$45,$3E,$00,$42,$7F,$40,$00,$72,$49,$49,$49,$46,_	'0,1,2
    					$21,$41,$49,$4D,$33,$18,$14,$12,$7F,$10,$27,$45,$45,$45,$39,_	'3,4,5
    					$3C,$4A,$49,$49,$31,$41,$21,$11,$09,$07,$36,$49,$49,$49,$36,_	'6,7,8
    					$46,$49,$49,$29,$1E,$00,$00,$14,$00,$00,$00,$40,$34,$00,$00,_	'9,:,;
    					$00,$08,$14,$22,$41,$14,$14,$14,$14,$14,$00,$41,$22,$14,$08,_	'<,=,>
    					$02,$01,$59,$09,$06,$3E,$41,$5D,$59,$4E],LCD_DATA	'?,@
    	elseif  (letter_reg < "[") then 
    	chartmp = charset - 165		' subtract previous table length so "A" = zero 					
    	lookup chartmp,[$7C,$12,$11,$12,$7C,_	'A
    					$7F,$49,$49,$49,$36,$3E,$41,$41,$41,$22,$7F,$41,$41,$41,$3E,_	'B,C,D
    					$7F,$49,$49,$49,$41,$7F,$09,$09,$09,$01,$3E,$41,$41,$51,$73,_	'E,F,G
    					$7F,$08,$08,$08,$7F,$00,$41,$7F,$41,$00,$20,$40,$41,$3F,$01,_	'H,I,J
    					$7F,$08,$14,$22,$41,$7F,$40,$40,$40,$40,$7F,$02,$1C,$02,$7F,_	'K,L,M
    					$7F,$04,$08,$10,$7F,$3E,$41,$41,$41,$3E,$7F,$09,$09,$09,$06,_	'N,O,P
    					$3E,$41,$51,$21,$5E,$7F,$09,$19,$29,$46,$26,$49,$49,$49,$32,_	'Q,R,S
    					$03,$01,$7F,$01,$03,$3F,$40,$40,$40,$3F,$1F,$20,$40,$20,$1F,_	'T,U,V
    					$3F,$40,$38,$40,$3F,$63,$14,$08,$14,$63,$03,$04,$78,$04,$03,_	'W,X,Y
    					$61,$59,$49,$4D,$43],LCD_DATA	'Z
    	else  
    	chartmp = charset - 295		' subtract previous tables length so "[" = zero
    	lookup chartmp,[$00,$7F,$41,$41,$41,$02,$04,$08,$10,$20,_	'[,\
    					$00,$41,$41,$41,$7F,$04,$02,$01,$02,$04,$40,$40,$40,$40,$40,_	'],^,_
    					$00,$03,$07,$08,$00,$20,$54,$54,$38,$40,$7F,$28,$44,$44,$38,_	'`,a,b
    					$38,$44,$44,$44,$28,$38,$44,$44,$28,$7F,$38,$54,$54,$54,$18,_	'c,d,e
    					$00,$08,$7E,$09,$02,$0C,$52,$52,$4A,$3C,$7F,$08,$04,$04,$78,_	'f,g,h
    					$00,$44,$7D,$40,$00,$20,$40,$40,$3D,$00,$7F,$10,$28,$44,$00,_	'i,j,k
    					$00,$41,$7F,$40,$00,$7C,$04,$78,$04,$78,$7C,$08,$04,$04,$78,_	'l,m,n
    					$38,$44,$44,$44,$38,$7C,$18,$24,$24,$18,$18,$24,$24,$18,$7C,_	'o,p,q
    					$7C,$08,$04,$04,$08,$48,$54,$54,$54,$24,$04,$04,$3F,$44,$24,_	'r,s,t
    					$3C,$40,$40,$20,$7C,$1C,$20,$40,$20,$1C,$3C,$40,$30,$40,$3C,_	'u,v,w
    					$44,$28,$10,$28,$44,$4C,$50,$50,$50,$3C,$44,$64,$54,$4C,$44,_	'x,y,z
    					$00,$08,$36,$41,$00,$00,$00,$77,$00,$00,$00,$41,$36,$08,$00,_	'{,|,}
    					$02,$01,$02,$04,$02],LCD_DATA	'~
    	endif
        gosub SEND_DATA
        next charset
    	LCD_DATA = $00		' space between characters always $00 
        gosub SEND_DATA
    	return
    
    '===============================================================================

    IDE says this compiles in less than 4K so I tried the 16F877 and that compiles as well.
    Regards
    TimC
    Last edited by timc; - 17th July 2015 at 04:06. Reason: added the user name elcrcp

  5. #5
    Join Date
    Jan 2005
    Location
    Boston MA
    Posts
    19


    Did you find this post helpful? Yes | No

    Default Re: Cannot drive I2C Oled :(

    The INIT routine is critical and no single INIT routine will work for all SSD1306 displays. If you get your display to work in under an hour consider yourself lucky. This INIT routine can replace the one from elcrcp above if your display did not work. I have tried this same "routine" for both PIC's, AVR's and in Basic and C.
    Regards
    TimC



    Code:
    '==================    SSD1306 I2C OLED initialization   ======================
    INIT:
    I2CWrite SDA,SCL,I2CDevice,[DC,$AE]'Display OFF
    I2CWrite SDA,SCL,I2CDevice,[DC,$D3,$00]' Set offset to 0
    'I2CWrite SDA,SCL,I2CDevice,[DC,$40]' Set display start line 0, usually not needed
    I2CWrite SDA,SCL,I2CDevice,[DC,$8D,$14]' Set Charge Pump Internal, USUALLY needed
    I2CWrite SDA,SCL,I2CDevice,[DC,$20,$10]' Adressing mode $10=Page, $00=Horizontal
    I2CWrite SDA,SCL,I2CDevice,[DC,$A1]' set segment remap column 127 as start
    i2cwrite sda,scl,I2CDevice,[DC,$C8]' Com Scan Direction, Flip display vertically
    i2cwrite sda,scl,I2CDevice,[DC,$DA,$12]' set COM pins = 128x64=$12   128x32=$02
    I2CWrite SDA,SCL,I2CDevice,[DC,$81,$7F]' Set contrast to $01 to $FF  ($7F is default, $01 is faint)
    I2CWrite SDA,SCL,I2CDevice,[DC,$A4]' display ON continue
    I2CWrite SDA,SCL,I2CDevice,[DC,$A6]' $A6=NORMAL MODE;  $A7=INVERSE MODE
    I2CWrite SDA,SCL,I2CDevice,[DC,$AF]'Display ON
    ' longer delay here because we need to see if display shows random bytes.
    ' If you see random bytes - your display and INIT are probably working!
    pause 500	' remove when you like
    Wait what's DC? Well it should be $00 but I have read it might be $80. Is this why they are only $4 on EBAY?

  6. #6
    Join Date
    Apr 2013
    Posts
    32


    Did you find this post helpful? Yes | No

    Default Re: Cannot drive I2C Oled :(

    Good question there timc
    I realised that I forgot setting DC in init after some time.
    Funny Fact: After I set DC to $80 for INIT routine, oled not worked properly (or maybe not worked at all, can't remember right now) while SET_XY routine working fine with DC $80. So actually I'm not sure if command mode is 00 or 80 but it's working this way

  7. #7
    Join Date
    Apr 2013
    Posts
    32


    Did you find this post helpful? Yes | No

    Default Re: Cannot drive I2C Oled :(

    By the way TimC, your character table is clearly more efficient and Flash friendly. I will try it too when I have opportunity.
    But I want to ask something first; I'm not sure how LOOKUP and LOOKUP2 commands treats different data types, so that is why I'm asking this, lets say I wrote;
    "lookup2 variable,['string',variable2],variable3"
    And variable 2 contains 7 as data.
    Now, since string and variable2 are different data types, will this char table be able to recognize them both? I mean, is it working for both of '7' and 7 ?
    I'm just asking because I really don't know the behavior of lookup commands for different data types.

  8. #8
    Join Date
    Jan 2005
    Location
    Boston MA
    Posts
    19


    Did you find this post helpful? Yes | No

    Default Re: Cannot drive I2C Oled :(

    Personally I would not alternate different data types in a big character table because you want to make it as simple and small as possible. From the PBP manual it says: "Lookup2 generates code that is about 3 times larger then Lookup."
    So I went back to Lookup. The only other reason that you might use Lookup2 is because it can address 1024 values. The new manual for V3 says Lookup can address 1024 values but it failed after "S" and before it reached "T" which is exactly 256 values.

    Me thinks the V3.0.8 compiler has a bug!

  9. #9
    Join Date
    Jan 2005
    Location
    Boston MA
    Posts
    19


    Did you find this post helpful? Yes | No

    Default Re: Cannot drive I2C Oled :(

    I posted a full demo of a SSD1306 add-in over on the code example forum. elcrcp I think this is what you were asking for earlier.
    Best part is you can start to use it like a regular LCD with data from other devices and formatted output.

    http://www.picbasic.co.uk/forum/showthread.php?t=20179

    TimC

Similar Threads

  1. OLED 128X96 cheap china lcd
    By starwick in forum Code Examples
    Replies: 10
    Last Post: - 19th June 2017, 05:23
  2. Help With OLED Display / 128X64 SSD1306
    By Denner in forum General
    Replies: 6
    Last Post: - 25th May 2013, 15:40
  3. SEROUT + SERIN, OLED + PICAXE coding help required
    By SeanHowson in forum mel PIC BASIC
    Replies: 4
    Last Post: - 15th October 2012, 16:11
  4. Master SPI interface to LCD/OLED??
    By jellis00 in forum mel PIC BASIC Pro
    Replies: 7
    Last Post: - 19th September 2009, 23:44
  5. OLED 128x128 color display
    By Ron Marcus in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 21st May 2007, 01:45

Members who have read this thread : 2

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

Tags for this Thread

Posting Permissions

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