Cannot drive I2C Oled :(


Closed Thread
Results 1 to 22 of 22

Hybrid View

  1. #1
    Join Date
    Apr 2013
    Posts
    32


    Did you find this post helpful? Yes | No

    Default Re: Cannot drive I2C Oled :(

    Hi guys, I again thank you for your code examples Sherbrook. Now I completed my codes and I think they can be helpful.
    Anyway I wanted to share my codes for others too. Maybe someone can improve and chage them into a include file.

    By the way, is it possible to use a variable's content in a lookup table? I'll try to print out variable contents on screen but I'm not sure the way right now. I think I'll open a new thread for this =)

    Code:
    'This code is for driving an OLED screen
    'My screen was 0.96" 128x64 B/W SSD1306 chip with I2C protocol
    'I used a 16f877a, you must change definitions and register settings due to 
    'your hardware.
    'This code have a large char library in it, so it takes some memory, you may
    'delete some of chars you won't use if you need some space for your program
    'My codes don't include bitmap drawing I only intended to write texts on screen
    'So if you want to draw bitmap, you must alter printing codes.
    'Now
    'Screen contains 8 lines (which are 8 pixel height) and 128 columns
    'there are 1 printout subroutine for each Line, Simply change the X value on
    'that line's subroutine and your text will start from that column.
    'There also 8 text sobroutines which are contains text for each line, you can 
    'write your text on these subroutines, but !!!REMEMBER!!! to change the first
    'value of lookup table to number of chars u used in your text.
    
       
    '==========================MCU SETUP============================================  
    DEFINE OSC 16
    OPTION_REG=0
    ADCON0=0
    ADCON1=7
    TRISA=%00111111
    TRISB=%00000001
    TRISC=0
    PORTC=$FF
    
    '==============================BAUD SETUP=======================================
    
    I2CDevice var byte
    SCL var PortC.3         ' I2C Clock  PortC.3
    SDA var PortC.4         ' I2C Data   PortC.4
    DC VAR byte' "DATA OR COMMAND", $40=DATA; $80=COMMAND
    LCD_DATA VAR BYTE
    COM VAR BYTE'COMMAND
    X VAR BYTE' LCD Column POSITION (0 TO 127)
    Y VAR BYTE'LCD Line POSITION FOR PAGE MODE(0 TO 7)
    I var byte
    charset var byte 'Char codes index
    say var byte     'counter 
    text_reg var byte 'index for text
    letter_reg var byte 'data carrier for text chars
    letter_count var byte 'count of letters in your text
    CLEAR
    '=============================================================================
    I2CDevice = $78      ' Display = $78,
    PAUSE 20
    '=========================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
    '===============================================================================
    GOSUB CLEAR_LCD
    pause 500
    
    MAIN:
    
    gosub Print_Line_0
    gosub Print_Line_1
    gosub Print_Line_2
    gosub Print_Line_3
    gosub Print_Line_4
    'gosub Print_Line_5 'You can comment out the lines you don't want to use
    'gosub Print_Line_6
    'gosub Print_Line_7
    
    sleep 5
    
    GOTO MAIN
    
    '=============================Text to Write=====================================
    Line_0:
    lookup text_reg,[4,"Test"],letter_reg' first data is number of chars in your
    'text
    return
    
    Line_1:
    lookup text_reg,[9,"Test teST"],letter_reg' first data is number of chars in your
    'text
    return
    
    Line_2:
    lookup text_reg,[7,"T e s t"],letter_reg' first data is number of chars in your
    'text
    return
    
    Line_3:
    lookup text_reg,[8,"%]Test{-"],letter_reg' first data is number of chars in your
    'text
    return
    
    Line_4:
    lookup text_reg,[7,"Hop Hop"],letter_reg' first data is number of chars in your
    'text
    return
    
    Line_5:
    lookup text_reg,[4,"Test"],letter_reg' first data is number of chars in your
    'text
    return
    
    Line_6:
    lookup text_reg,[4,"Test"],letter_reg' first data is number of chars in your
    'text
    return
    
    Line_7:
    lookup text_reg,[4,"Test"],letter_reg' first data is number of chars in your
    'text
    return
    
    '======================Print Lines==============================================
    Print_Line_0:
    X=0 'You can change this value to set starting column
    Y=0 'Don't change this line
    gosub SET_XY
    gosub Line_0
    letter_count=letter_reg
    text_reg=text_reg+1
    for say=1 to letter_count
        gosub Line_0
        gosub Find_Char
        text_reg=text_reg+1
    next say
    text_reg=0
    return
    
    Print_Line_1:
    X=10 'You can change this value to set starting column
    Y=1  'Don't change this line
    gosub SET_XY
    gosub Line_1
    letter_count=letter_reg
    text_reg=text_reg+1
    for say=1 to letter_count
        gosub Line_1
        gosub Find_Char
        text_reg=text_reg+1
    next say
    text_reg=0
    return
    
    Print_Line_2:
    X=20 'You can change this value to set starting column
    Y=2  'Don't change this line
    gosub SET_XY
    gosub Line_2
    letter_count=letter_reg
    text_reg=text_reg+1
    for say=1 to letter_count
        gosub Line_2
        gosub Find_Char
        text_reg=text_reg+1
    next say
    text_reg=0
    return
    
    Print_Line_3:
    X=30 'You can change this value to set starting column
    Y=3  'Don't change this line
    gosub SET_XY
    gosub Line_3
    letter_count=letter_reg
    text_reg=text_reg+1
    for say=1 to letter_count
        gosub Line_3
        gosub Find_Char
        text_reg=text_reg+1
    next say
    text_reg=0
    return
    
    Print_Line_4:
    X=40  'You can change this value to set starting column
    Y=4   'Don't change this line
    gosub SET_XY
    gosub Line_4
    letter_count=letter_reg
    text_reg=text_reg+1
    for say=1 to letter_count
        gosub Line_4
        gosub Find_Char
        text_reg=text_reg+1
    next say
    text_reg=0
    return
    
    Print_Line_5:
    X=50  'You can change this value to set starting column
    Y=5   'Don't change this line
    gosub SET_XY
    gosub Line_5
    letter_count=letter_reg
    text_reg=text_reg+1
    for say=1 to letter_count
        gosub Line_5
        gosub Find_Char
        text_reg=text_reg+1
    next say
    text_reg=0
    return
    
    Print_Line_6:
    X=60  'You can change this value to set starting column
    Y=6   'Don't change this line
    gosub SET_XY
    gosub Line_6
    letter_count=letter_reg
    text_reg=text_reg+1
    for say=1 to letter_count
        gosub Line_6
        gosub Find_Char
        text_reg=text_reg+1
    next say
    text_reg=0
    return
    
    Print_Line_7:
    X=55  'You can change this value to set starting column
    Y=7   'Don't change this line
    gosub SET_XY
    gosub Line_7
    letter_count=letter_reg
    text_reg=text_reg+1
    for say=1 to letter_count
        gosub Line_7
        gosub Find_Char
        text_reg=text_reg+1
    next say
    text_reg=0
    return
    '===============================================================================
    
    '=======================Send data===============================================
    SEND_DATA:
    DC=$40
    I2CWrite SDA,SCL,I2CDevice,[DC,LCD_DATA]
    RETURN
    '===============================================================================
    '======================Send Command=============================================
    SEND_COMMAND:
    DC=$80
    I2CWrite SDA,SCL,I2CDevice,[DC,COM]
    RETURN
    '===============================================================================
    
    '==============================clear lcd========================================
    CLEAR_LCD:
    X=0
    Y=0
    LCD_DATA=$00
    'Send 0 to every column in every line
    FOR Y=0 TO 7
        gosub SET_XY
        FOR I=0 TO 127
            GOSUB SEND_DATA
        NEXT I
    NEXT Y
    X=0
    Y=0 
    gosub SET_XY                            
    RETURN 
    '=============================Find Char=========================================
    Find_Char:
    select case letter_reg
        case " "
        for charset=0 to 5
        lookup charset,[$00,$00,$00,$00,$00,$00],LCD_DATA
        gosub SEND_DATA 
        next charset
        return
    case "!"
      	for charset=0 to 5
      	lookup charset,[$00,$00,$5F,$00,$00,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "#"
      	for charset=0 to 5
      	lookup charset,[$14,$7F,$14,$7F,$14,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "$"
      	for charset=0 to 5
      	lookup charset,[$24,$2A,$7F,$2A,$12,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "%"
      	for charset=0 to 5
      	lookup charset,[$23,$13,$08,$64,$62,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "&"
      	for charset=0 to 5
      	lookup charset,[$36,$49,$56,$20,$50,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "'"
      	for charset=0 to 5
      	lookup charset,[$00,$08,$07,$03,$00,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "("
      	for charset=0 to 5
      	lookup charset,[$00,$1C,$22,$41,$00,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case ")"
      	for charset=0 to 5
      	lookup charset,[$00,$41,$22,$1C,$00,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "*"
      	for charset=0 to 5
      	lookup charset,[$2A,$1C,$7F,$1C,$2A,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "+"
      	for charset=0 to 5
      	lookup charset,[$08,$08,$3E,$08,$08,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case ","
      	for charset=0 to 5
      	lookup charset,[$00,$00,$70,$30,$00,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "-"
      	for charset=0 to 5
      	lookup charset,[$08,$08,$08,$08,$08,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "."
      	for charset=0 to 5
      	lookup charset,[$00,$00,$60,$60,$00,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "/"
      	for charset=0 to 5
      	lookup charset,[$20,$10,$08,$04,$02,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "0"
      	for charset=0 to 5
      	lookup charset,[$3E,$51,$49,$45,$3E,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "1"
      	for charset=0 to 5
      	lookup charset,[$00,$42,$7F,$40,$00,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "2"
      	for charset=0 to 5
      	lookup charset,[$72,$49,$49,$49,$46,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "3"
      	for charset=0 to 5
      	lookup charset,[$21,$41,$49,$4D,$33,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "4"
      	for charset=0 to 5
      	lookup charset,[$18,$14,$12,$7F,$10,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "5"
      	for charset=0 to 5
      	lookup charset,[$27,$45,$45,$45,$39,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "6"
      	for charset=0 to 5
      	lookup charset,[$3C,$4A,$49,$49,$31,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "7"
      	for charset=0 to 5
      	lookup charset,[$41,$21,$11,$09,$07,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "8"
      	for charset=0 to 5
      	lookup charset,[$36,$49,$49,$49,$36,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "9"
      	for charset=0 to 5
      	lookup charset,[$46,$49,$49,$29,$1E,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case ":"
      	for charset=0 to 5
      	lookup charset,[$00,$00,$14,$00,$00,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case ";"
      	for charset=0 to 5
      	lookup charset,[$00,$40,$34,$00,$00,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "<"
      	for charset=0 to 5
      	lookup charset,[$00,$08,$14,$22,$41,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "="
      	for charset=0 to 5
      	lookup charset,[$14,$14,$14,$14,$14,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case ">"
      	for charset=0 to 5
      	lookup charset,[$00,$41,$22,$14,$08,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "?"
      	for charset=0 to 5
      	lookup charset,[$02,$01,$59,$09,$06,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "@"
      	for charset=0 to 5
      	lookup charset,[$3E,$41,$5D,$59,$4E,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "A"
      	for charset=0 to 5
      	lookup charset,[$7C,$12,$11,$12,$7C,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "B"
      	for charset=0 to 5
      	lookup charset,[$7F,$49,$49,$49,$36,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "C"
      	for charset=0 to 5
      	lookup charset,[$3E,$41,$41,$41,$22,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "D"
      	for charset=0 to 5
      	lookup charset,[$7F,$41,$41,$41,$3E,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "E"
      	for charset=0 to 5
      	lookup charset,[$7F,$49,$49,$49,$41,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "F"
      	for charset=0 to 5
      	lookup charset,[$7F,$09,$09,$09,$01,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "G"
      	for charset=0 to 5
      	lookup charset,[$3E,$41,$41,$51,$73,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "H"
      	for charset=0 to 5
      	lookup charset,[$7F,$08,$08,$08,$7F,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "I"
      	for charset=0 to 5
      	lookup charset,[$00,$41,$7F,$41,$00,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "J"
      	for charset=0 to 5
      	lookup charset,[$20,$40,$41,$3F,$01,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "K"
      	for charset=0 to 5
      	lookup charset,[$7F,$08,$14,$22,$41,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "L"
      	for charset=0 to 5
      	lookup charset,[$7F,$40,$40,$40,$40,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "M"
      	for charset=0 to 5
      	lookup charset,[$7F,$02,$1C,$02,$7F,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "N"
      	for charset=0 to 5
      	lookup charset,[$7F,$04,$08,$10,$7F,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "O"
      	for charset=0 to 5
      	lookup charset,[$3E,$41,$41,$41,$3E,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "P"
      	for charset=0 to 5
      	lookup charset,[$7F,$09,$09,$09,$06,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "Q"
      	for charset=0 to 5
      	lookup charset,[$3E,$41,$51,$21,$5E,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "R"
      	for charset=0 to 5
      	lookup charset,[$7F,$09,$19,$29,$46,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "S"
      	for charset=0 to 5
      	lookup charset,[$26,$49,$49,$49,$32,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "T"
      	for charset=0 to 5
      	lookup charset,[$03,$01,$7F,$01,$03,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "U"
      	for charset=0 to 5
      	lookup charset,[$3F,$40,$40,$40,$3F,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "V"
      	for charset=0 to 5
      	lookup charset,[$1F,$20,$40,$20,$1F,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "W"
      	for charset=0 to 5
      	lookup charset,[$3F,$40,$38,$40,$3F,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "X"
      	for charset=0 to 5
      	lookup charset,[$63,$14,$08,$14,$63,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "Y"
      	for charset=0 to 5
      	lookup charset,[$03,$04,$78,$04,$03,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "Z"
      	for charset=0 to 5
      	lookup charset,[$61,$59,$49,$4D,$43,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "["
      	for charset=0 to 5
      	lookup charset,[$00,$7F,$41,$41,$41,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "\"
      	for charset=0 to 5
      	lookup charset,[$02,$04,$08,$10,$20,$00	 ],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "]"
      	for charset=0 to 5
      	lookup charset,[$00,$41,$41,$41,$7F,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "^"
      	for charset=0 to 5
      	lookup charset,[$04,$02,$01,$02,$04,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "_"
      	for charset=0 to 5
      	lookup charset,[$40,$40,$40,$40,$40,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "`"
      	for charset=0 to 5
      	lookup charset,[$00,$03,$07,$08,$00,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "a"
      	for charset=0 to 5
      	lookup charset,[$20,$54,$54,$38,$40,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "b"
      	for charset=0 to 5
      	lookup charset,[$7F,$28,$44,$44,$38,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "c"
      	for charset=0 to 5
      	lookup charset,[$38,$44,$44,$44,$28,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "d"
      	for charset=0 to 5
      	lookup charset,[$38,$44,$44,$28,$7F,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "e"
      	for charset=0 to 5
      	lookup charset,[$38,$54,$54,$54,$18,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "f"
      	for charset=0 to 5
      	lookup charset,[$00,$08,$7E,$09,$02,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "g"
      	for charset=0 to 5
      	lookup charset,[$0C,$52,$52,$4A,$3C,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "h"
      	for charset=0 to 5
      	lookup charset,[$7F,$08,$04,$04,$78,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "i"
      	for charset=0 to 5
      	lookup charset,[$00,$44,$7D,$40,$00,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "j"
      	for charset=0 to 5
      	lookup charset,[$20,$40,$40,$3D,$00,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "k"
      	for charset=0 to 5
      	lookup charset,[$7F,$10,$28,$44,$00,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "l"
      	for charset=0 to 5
      	lookup charset,[$00,$41,$7F,$40,$00,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "m"
      	for charset=0 to 5
      	lookup charset,[$7C,$04,$78,$04,$78,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "n"
      	for charset=0 to 5
      	lookup charset,[$7C,$08,$04,$04,$78,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "o"
      	for charset=0 to 5
      	lookup charset,[$38,$44,$44,$44,$38,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "p"
      	for charset=0 to 5
      	lookup charset,[$7C,$18,$24,$24,$18,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "q"
      	for charset=0 to 5
      	lookup charset,[$18,$24,$24,$18,$7C,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "r"
      	for charset=0 to 5
      	lookup charset,[$7C,$08,$04,$04,$08,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "s"
      	for charset=0 to 5
      	lookup charset,[$48,$54,$54,$54,$24,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "t"
      	for charset=0 to 5
      	lookup charset,[$04,$04,$3F,$44,$24,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "u"
      	for charset=0 to 5
      	lookup charset,[$3C,$40,$40,$20,$7C,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "v"
      	for charset=0 to 5
      	lookup charset,[$1C,$20,$40,$20,$1C,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "w"
      	for charset=0 to 5
      	lookup charset,[$3C,$40,$30,$40,$3C,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "x"
      	for charset=0 to 5
      	lookup charset,[$44,$28,$10,$28,$44,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "y"
      	for charset=0 to 5
      	lookup charset,[$4C,$50,$50,$50,$3C,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "z"
      	for charset=0 to 5
      	lookup charset,[$44,$64,$54,$4C,$44,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "{"
      	for charset=0 to 5
      	lookup charset,[$00,$08,$36,$41,$00,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "|"
      	for charset=0 to 5
      	lookup charset,[$00,$00,$77,$00,$00,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "}"
      	for charset=0 to 5
      	lookup charset,[$00,$41,$36,$08,$00,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    case "~"
      	for charset=0 to 5
      	lookup charset,[$02,$01,$02,$04,$02,$00],LCD_DATA
      	gosub SEND_DATA
      	next charset
      	return
    end select
    return
    '===============================================================================
    '=========================CHAR_SET==============================================
    
    '===========================================SET X AND Y=========================
    SET_XY:
    COM=$21:GOSUB SEND_COMMAND
    COM=X:GOSUB SEND_COMMAND
    COM=127:GOSUB SEND_COMMAND
    'Above 3 lines means; Column starts at X and End at 127
    COM=$22:GOSUB SEND_COMMAND
    COM=Y:GOSUB SEND_COMMAND
    COM=Y:GOSUB SEND_COMMAND
    'Above 3 lines means; Line starts at Y and end at Y, 
    'which means ; Only work on specified line!
    RETURN
    '===============================================================================
    END

  2. #2
    Join Date
    Feb 2013
    Posts
    1,124


    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.

  3. #3
    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.

  4. #4
    Join Date
    Feb 2013
    Posts
    1,124


    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.

  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 :(

    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

  6. #6
    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?

  7. #7
    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

  8. #8
    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.

  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 :(

    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!

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 : 3

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