OLED display met ST7789 en MikroBasic

Bavelt

Golden Member

Ik ben nu aan het testen met een 1,3"Oled display, 240 * 240 met SPI interface (IC: ST7789).
Ik heb geprobeerd om het programma van Arco om te te zetten naar een PIC16F887, maar lukt niet echt:

pic basic code:


e MikroBasic code om te testen (past nog in de demo versie van de dsPic compiler):

pic basic code:


'==================================================================================================
' Project name: Test_Oled              - CONFIG1 : 0x3F7F
' MCU:          PIC24FJ256GA106        - CONFIG2 : 0x92BE
' Oscillator:   HS, 8.0000 MHz         - CONFIG3 : 0xFFFF
'==================================================================================================
program Test_Oled

Dim SSel         As sBit At LATD.9                              'Display select
    D_C          As sBit At LATF.5                              'Data/Command

const Char6x8 As Byte[570] = (       'Character table
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  ' sp
0x00, 0x00, 0x00, 0x2f, 0x00, 0x00,  ' !
0x00, 0x00, 0x07, 0x00, 0x07, 0x00,  ' "
0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14,  ' #
0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12,  ' $
0x00, 0x62, 0x64, 0x08, 0x13, 0x23,  ' %
0x00, 0x36, 0x49, 0x55, 0x22, 0x50,  ' &
0x00, 0x00, 0x05, 0x03, 0x00, 0x00,  ' '
0x00, 0x00, 0x1c, 0x22, 0x41, 0x00,  ' (
0x00, 0x00, 0x41, 0x22, 0x1c, 0x00,  ' )
0x00, 0x14, 0x08, 0x3E, 0x08, 0x14,  ' *
0x00, 0x08, 0x08, 0x3E, 0x08, 0x08,  ' +
0x00, 0x00, 0x00, 0xA0, 0x60, 0x00,  ' ,
0x00, 0x08, 0x08, 0x08, 0x08, 0x08,  ' -
0x00, 0x00, 0x60, 0x60, 0x00, 0x00,  ' .
0x00, 0x20, 0x10, 0x08, 0x04, 0x02,  ' /
0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E,  ' 0
0x00, 0x00, 0x42, 0x7F, 0x40, 0x00,  ' 1
0x00, 0x42, 0x61, 0x51, 0x49, 0x46,  ' 2
0x00, 0x21, 0x41, 0x45, 0x4B, 0x31,  ' 3
0x00, 0x18, 0x14, 0x12, 0x7F, 0x10,  ' 4
0x00, 0x27, 0x45, 0x45, 0x45, 0x39,  ' 5
0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30,  ' 6
0x00, 0x01, 0x71, 0x09, 0x05, 0x03,  ' 7
0x00, 0x36, 0x49, 0x49, 0x49, 0x36,  ' 8
0x00, 0x06, 0x49, 0x49, 0x29, 0x1E,  ' 9
0x00, 0x00, 0x36, 0x36, 0x00, 0x00,  ' :
0x00, 0x00, 0x56, 0x36, 0x00, 0x00,  ' ;
0x00, 0x08, 0x14, 0x22, 0x41, 0x00,  ' <
0x00, 0x14, 0x14, 0x14, 0x14, 0x14,  ' =
0x00, 0x00, 0x41, 0x22, 0x14, 0x08,  ' >
0x00, 0x02, 0x01, 0x51, 0x09, 0x06,  ' ?
0x00, 0x32, 0x49, 0x59, 0x51, 0x3E,  ' @
0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C,  ' A
0x00, 0x7F, 0x49, 0x49, 0x49, 0x36,  ' B
0x00, 0x3E, 0x41, 0x41, 0x41, 0x22,  ' C
0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C,  ' D
0x00, 0x7F, 0x49, 0x49, 0x49, 0x41,  ' E
0x00, 0x7F, 0x09, 0x09, 0x09, 0x01,  ' F
0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A,  ' G
0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F,  ' H
0x00, 0x00, 0x41, 0x7F, 0x41, 0x00,  ' I
0x00, 0x20, 0x40, 0x41, 0x3F, 0x01,  ' J
0x00, 0x7F, 0x08, 0x14, 0x22, 0x41,  ' K
0x00, 0x7F, 0x40, 0x40, 0x40, 0x40,  ' L
0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F,  ' M
0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F,  ' N
0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E,  ' O
0x00, 0x7F, 0x09, 0x09, 0x09, 0x06,  ' P
0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E,  ' Q
0x00, 0x7F, 0x09, 0x19, 0x29, 0x46,  ' R
0x00, 0x46, 0x49, 0x49, 0x49, 0x31,  ' S
0x00, 0x01, 0x01, 0x7F, 0x01, 0x01,  ' T
0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F,  ' U
0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F,  ' V
0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F,  ' W
0x00, 0x63, 0x14, 0x08, 0x14, 0x63,  ' X
0x00, 0x07, 0x08, 0x70, 0x08, 0x07,  ' Y
0x00, 0x61, 0x51, 0x49, 0x45, 0x43,  ' Z
0x00, 0x00, 0x7F, 0x41, 0x41, 0x00,  ' [
0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55,  ' \
0x00, 0x00, 0x41, 0x41, 0x7F, 0x00,  ' ]
0x00, 0x04, 0x02, 0x01, 0x02, 0x04,  ' ^
0x00, 0x40, 0x40, 0x40, 0x40, 0x40,  ' _
0x00, 0x00, 0x01, 0x02, 0x04, 0x00,  ' '
0x00, 0x20, 0x54, 0x54, 0x54, 0x78,  ' a
0x00, 0x7F, 0x48, 0x44, 0x44, 0x38,  ' b
0x00, 0x38, 0x44, 0x44, 0x44, 0x20,  ' c
0x00, 0x38, 0x44, 0x44, 0x48, 0x7F,  ' d
0x00, 0x38, 0x54, 0x54, 0x54, 0x18,  ' e
0x00, 0x08, 0x7E, 0x09, 0x01, 0x02,  ' f
0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C,  ' g
0x00, 0x7F, 0x08, 0x04, 0x04, 0x78,  ' h
0x00, 0x00, 0x44, 0x7D, 0x40, 0x00,  ' i
0x00, 0x40, 0x80, 0x84, 0x7D, 0x00,  ' j
0x00, 0x7F, 0x10, 0x28, 0x44, 0x00,  ' k
0x00, 0x00, 0x41, 0x7F, 0x40, 0x00,  ' l
0x00, 0x7C, 0x04, 0x18, 0x04, 0x78,  ' m
0x00, 0x7C, 0x08, 0x04, 0x04, 0x78,  ' n
0x00, 0x38, 0x44, 0x44, 0x44, 0x38,  ' o
0x00, 0xFC, 0x24, 0x24, 0x24, 0x18,  ' p
0x00, 0x18, 0x24, 0x24, 0x18, 0xFC,  ' q
0x00, 0x7C, 0x08, 0x04, 0x04, 0x08,  ' r
0x00, 0x48, 0x54, 0x54, 0x54, 0x20,  ' s
0x00, 0x04, 0x3F, 0x44, 0x40, 0x20,  ' t
0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C,  ' u
0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C,  ' v
0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C,  ' w
0x00, 0x44, 0x28, 0x10, 0x28, 0x44,  ' x
0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C,  ' y
0x00, 0x44, 0x64, 0x54, 0x4C, 0x44,  ' z
0x00, 0x10, 0x6C, 0x82, 0x00, 0x00,  ' {
0x00, 0x00, 0x00, 0xFE, 0x00, 0x00,  ' |
0x00, 0x00, 0x00, 0x82, 0x6C, 0x10,  ' }
0x14, 0x14, 0x14, 0x14, 0x14, 0x14)  ' horiz lines

'==================================================================================================
Sub Procedure Init_App()                                        'Initialize pillbox
'==================================================================================================
  Dim lRet As Byte
  delay_ms(100)
  TRISD         = %0000000000001011                             '
  TRISF         = %0000000000000000                             '
  LATD          = %0000001000000010                             '
  LATF          = %0000000000000000                             '

  Unlock_IOLock()
  PPS_Mapping_NoLock( 3,_OUTPUT,_SDO1)                          'RP3  (= LATD.10 pin)
  PPS_Mapping_NoLock(12,_OUTPUT,_SCK1OUT)                       'RP12 (= LATD.11 pin)
  Lock_IOLock()
  Spi1_Init_Advanced(_SPI_MASTER, 
                     _SPI_8_BIT, 
                     _SPI_PRESCALE_SEC_1, 
                     _SPI_PRESCALE_PRI_16, 
                     _SPI_SS_DISABLE, 
                     _SPI_DATA_SAMPLE_MIDDLE, 
                     _SPI_CLK_IDLE_HIGH, 
                     _SPI_IDLE_2_ACTIVE)
  Delay_ms(100)
End Sub

'==================================================================================================
Sub Procedure Lcd_WrCmd(Dim pCmd As Byte)                       'Write command to display
'==================================================================================================
  D_C = 0
  Spi1_Write(pCmd)
End Sub

'==================================================================================================
Sub Procedure Lcd_WrDat(Dim pDat As Byte)                       'Write data to display
'==================================================================================================
  Dim lCnt As Byte
  D_C = 1
  Spi1_Write(pDat)
End Sub

'==================================================================================================
Sub Procedure Lcd_SetPos(Dim px, py as Byte)                    'Set write position on display
'==================================================================================================
  delay_us(1)
  Lcd_WrCmd(0xB0 + py)
  Lcd_WrCmd((px  >> 4) Or 0x10)
  Lcd_WrCmd((px And 0x0F)) 
  delay_us(1)
End Sub

'==================================================================================================
Sub Procedure LCD_Fill(Dim pFill As Byte)                       'Fill display with character pFill
'==================================================================================================
  Dim lx, ly As Byte
  For ly = 0 To 8
    Lcd_WrCmd(0xB0+ly)
    Lcd_WrCmd(0x01)
    Lcd_WrCmd(0x10)
    For lx = 0 to 131
      Lcd_WrDat(pFill)
    Next lx
  Next ly
End Sub

'==================================================================================================
Sub Procedure Lcd_Char_6x8(Dim px, py, pchar As Byte)           'Write one character
'==================================================================================================
  Dim lIndex As Word
  Lcd_SetPos(px, py)
  lIndex = pChar - 0x20
  lIndex = (lIndex << 2) + (lIndex << 1)
  Lcd_WrDat(Char6x8[lIndex+0])
  Lcd_WrDat(Char6x8[lIndex+1])
  Lcd_WrDat(Char6x8[lIndex+2])
  Lcd_WrDat(Char6x8[lIndex+3])
  Lcd_WrDat(Char6x8[lIndex+4])
  Lcd_WrDat(Char6x8[lIndex+5])
End Sub

'==================================================================================================
Sub Procedure Lcd_String_6x8(Dim px, py As Byte, Dim ByRef pDisp As String) ' Write string
'==================================================================================================
  Dim lLen, lCnt As Byte
  lLen = Length(pDisp)
  For lCnt = 0 To (lLen-1)
    If px >= 124 Then px = 0 py = py+1 End If
    Lcd_Char_6x8(px, py, pDisp[lCnt])
    px = px + 6
  Next lCnt
End Sub

'==================================================================================================
Main:                                                           'Main program
'==================================================================================================
    Init_App()                   'Initialize
    SSel = 0
    delay_ms(500)
    SSEL = 1                     'Only for 0.96", for 1.3" remove it
    
    delay_ms(500)
    Lcd_WrCmd(0xAE)              'Turn OLED panel off
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0xA8)              'Multiplex ratio set to
    Lcd_WrCmd(0x3F)              '63
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0xD3)              'Display offset RAM counter
    Lcd_WrCmd(0x00)              'none
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0x40)              'Start line address
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0xA1)              'Set segment remap rotation to left
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0xC8)              'Common output scan direction
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0xDA)              'Common signals pad
    Lcd_WrCmd(0x12)              'value
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0x81)              'Contrast control
    Lcd_WrCmd(0xFF)              'value
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0xA4)
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0xA6)              'Normal display
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0xD5)              'Clock ratio:oscillator frequency
    Lcd_WrCmd(0x80)              'oooo:rrrr
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0x8D)
    Lcd_WrCmd(0x14)
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0x00)              'Set lower column address
    Lcd_WrCmd(0x10)              'Set higher column address
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0xD9)              '15 clocks, discharge 1 clock
    Lcd_WrCmd(0xF1)              'dddd:pppp
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0xDB)              'Common output voltage
    Lcd_WrCmd(0x40)              'level
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0x20)              'Addressing mode
    Lcd_WrCmd(0x02)              'value
    '--------------------------------------------------------------------------
'    Lcd_WrCmd(0xA7)
    Lcd_Fill(0x00)
    Lcd_SetPos(0,0)
    '--------------------------------------------------------------------------
    Lcd_String_6x8(0,0,"Dit is een test van")
    Lcd_String_6x8(0,1,"een 128x64 pixel gra-")
    Lcd_String_6x8(0,2,"fisch OLED display.")
    Lcd_String_6x8(0,3,"Met 't 6x8 pixel font")
    Lcd_String_6x8(0,4,"gaat er heel wat in-")
    Lcd_String_6x8(0,5,"formatie op zo'n mini")
    Lcd_String_6x8(0,6,"scherm van 1.1x2.2cm")
    Lcd_String_6x8(0,7,"(en toch nog scherp!)")
    Lcd_WrCmd(0xAF)    'Turn OLED panel on
    delay_ms(500)

    SSel = 1
    While True
    Wend
End.

Deze routines

pic basic code:

 Unlock_IOLock()
  PPS_Mapping_NoLock( 3,_OUTPUT,_SDO1)                          'RP3  (= LATD.10 pin)
  PPS_Mapping_NoLock(12,_OUTPUT,_SCK1OUT)                       'RP12 (= LATD.11 pin)
  Lock_IOLock()
  Spi1_Init_Advanced(_SPI_MASTER, 
                     _SPI_8_BIT, 
                     _SPI_PRESCALE_SEC_1, 
                     _SPI_PRESCALE_PRI_16, 
                     _SPI_SS_DISABLE, 
                     _SPI_DATA_SAMPLE_MIDDLE, 
                     _SPI_CLK_IDLE_HIGH, 
                     _SPI_IDLE_2_ACTIVE)

lopen sowieso al niet (kunnen ws dus niet bij de 887).
Ik heb de poorten aangepast, maar zonder resultaat (display doet niks)

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Zou gewoon moeten werken. (als die ST7789 tenminste gelijk is aan de SSD1306)
Alleen de poorten en de SPI init aanpassen.

pic basic code:


  Spi1_Init_Advanced(_SPI_MASTER_OSC_DIV4,
                     _SPI_DATA_SAMPLE_MIDDLE,
                     _SPI_CLK_IDLE_HIGH,
                     _SPI_HIGH_2_LOW)

De lock/unlock sectie moet weg, de 887 heeft geen PPS...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Arco

Special Member

De ST7789 zie ik net is een compleet andere chip dus dat gaat zeker niet werken...
(is voor een color-TFT, niet voor een OLED)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Is inderdaad een color-led. Wilde ik ook eens mee stoeien.

Er zijn wel voorbeelden te vinden, maar ja, dan kom je uit Op Arduino of C...
Terwijl ik net zo lekker bezig ben met MikroBasic.
;)

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Voor een TFT moet minimaal 4x zoveel data verstuurd worden. (data, en RGB informatie voor elke pixel)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Ik ben al blij als ik het in zwart wit aan de praat krijg...

Fouten zijn het bewijs dat je het probeert..
KGE

Golden Member

Misschien kun je hier de initialisatieparameters uit halen:

https://github.com/adafruit/Adafruit-ST7735-Library/blob/master/Adafruit_ST7789.cpp

En het is dus geen OLED scherm maar een TFT met LED backlight, het werkt alleen maar op 3,3 Volt, op 5 Volt gaat de boel stuk...

Kleur of zwart/wit maakt voor de data die naar het scherm moet niet uit, dat blijft RGB, in dit geval 16 bit per pixel.

Dat MikroBasic ziet er al erg 'C' achtig uit dus de overstap naar Arduino is niet zo moeilijk denk ik. Is ook de programma grootte geen probleem meer.

Bavelt

Golden Member

Ok, Ik parkeer het TFT schermpje even. Daar ben ik dan nog niet aan toe vrees ik.

Dan even terug naar een 'echte' OLED, nu een 1,3 Inch met I2C protocol.
Daar gebeurt ook iets waar ik de vinger nog niet achter krijg.

Ik toon een byte, die steeds met 1 wordt opgehoogd. Op het scherm moet je dan de pixels 'binair' zien tellen. Dat gebeurt ook.

Maar het vreemde is, dat de eerste 'write' niet wordt getoond. En verder zie ik dat naast de binaire waarde op rij 8 ook steeds een pixel wordt getoond, maar dan op een positie tussen de getoonde andere.

Hier gebeurt dus iets vreemds of ik doe iets fout.

pic basic code:

'==============================================================================
program Oled_I2C_013
'------------------------------------------------------------------------------
Dim i1 as byte

'==================================================================================================
Sub Procedure Lcd_WrCmd(Dim pCmd As Byte)                       'Write data to display
'==================================================================================================
  while Not (i2c1_Is_Idle) wend
  i2c1_Start()
  i2c1_Wr(0x78)
  i2c1_Wr(0x80)
  i2c1_Wr(pCmd)
  i2c1_Stop()
End Sub

'==================================================================================================
Sub Procedure Lcd_WrDat(Dim pDat As Byte)                       'Write data to display
'==================================================================================================
  while Not (i2c1_Is_Idle) wend
  i2c1_Start()
  i2c1_Wr(0x78)
  i2c1_Wr(0x40)
  i2c1_Wr(pDat)
  Delay_ms(1)
  i2c1_Stop()
End Sub

'==================================================================================================
Sub Procedure Lcd_SetPos(Dim px, py as Byte)                    'Set write position on display
'==================================================================================================
  Lcd_WrCmd(0xB0 + py)
  Lcd_WrCmd(0xB0 + py)
  Lcd_WrCmd((px  >> 4) Or 0x10)
  Lcd_WrCmd(px And 0x0F)
End Sub

'===============================================================================
Sub Procedure LCD_Fill(Dim pFill As Byte)     'Fill display with character pFill
'===============================================================================
  Dim lx, ly As Byte
  For ly = 0 To 8
  LCD_wrCmd(0xB0 + ly)
  LCD_wrCmd(0x01)
  LCD_wrCmd(0x10)
    For lx = 0 to 131
      Lcd_wrDat(pFill)
    Next lx
  Next ly
End Sub

'===============================================================================
Sub Procedure Display_Init()
'===============================================================================
  Lcd_WrCmd(0xA8)                                 'Multiplex ratio set to
  Lcd_WrCmd(0x3F)                                 '63
  Lcd_WrCmd(0xD3)                                 'Display offset RAM counter
  Lcd_WrCmd(0x00)                                 'none
  Lcd_WrCmd(0x40)                                 'Start line address
  Lcd_WrCmd(0xA1)                                 'Set segment remap rotation to left
  Lcd_WrCmd(0xC8)                                 'Common output scan direction
  Lcd_WrCmd(0xDA)                                 'Common signals pad
  Lcd_WrCmd(0x12)                                 'value
  Lcd_WrCmd(0x81)                                 'Contrast control
  Lcd_WrCmd(0xFF)                                 'value
  Lcd_WrCmd(0xA4)
  Lcd_WrCmd(0xA6)                                 'Normal display
  Lcd_WrCmd(0xD5)                                 'Clock ratio:oscillator frequency
  Lcd_WrCmd(0x80)                                 'oooo:rrrr
  Lcd_WrCmd(0x8D)
  Lcd_WrCmd(0x14)
  Lcd_WrCmd(0x00)                                 'Set lower column address
  Lcd_WrCmd(0x10)                                 'Set higher column address
  Lcd_WrCmd(0xD9)                                 '15 clocks, discharge 1 clock
  Lcd_WrCmd(0xF1)                                 'dddd:pppp
  Lcd_WrCmd(0xDB)                                 'Common output voltage
  Lcd_WrCmd(0x40)                                 'level
  Lcd_WrCmd(0x20)                                 'Addressing mode
  Lcd_WrCmd(0x02)                                 'value
  Lcd_WrCmd(0xAE)                                 'Turn OLED panel off
End Sub

'==============================================================================
main:

''==============================================================================
  TRISC = %00000000
  Delay_ms(50)
  i2c1_init(100000)                              'Init i2c port 100kHz
  Display_Init()
  LCD_wrCmd(0xAF)                                'Turn Oled Panel on


 LCD_Fill(0x00)
 LCD_Setpos(0,0)

 while Not (i2c1_Is_Idle) wend
  i2c1_Start()
  i2c1_Wr(0x78)

  for i1 = 1 to 32
    i2c1_Wr(0x40)
    i2c1_Wr(i1)
    Delay_ms(1000)
  next i1
  
  i2c1_Stop()

 While True Wend
end. 
Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

zie foto (krijg hem niet goed scherp op kleine afstand)

[Bericht gewijzigd door Bavelt op maandag 23 december 2019 12:50:11 (51%)

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Die pixel steek je zelf aan met I2C1_Wr(0x40)... ;)
Lcd_WrDat() is wat netter, dan houd je ook niet de i2c bus voor een halve minuut open...

pic basic code:


  for i1 = 1 to 32
    Lcd_WrDat(i1)
    LCD_WrDat(0x00)   'Als je er een spatie tussen wilt
    Delay_ms(1000)
  next i1

[Bericht gewijzigd door Arco op maandag 23 december 2019 13:09:09 (11%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Ik zie het. Die 0x40 is de Control Byte, die aangeeft dat de volgende byte data is.
Ik had hem als data weggestuurd en inderdaad, stak ik de pixel aan.. 8)7

Blijft alleen waarom de allereerste write geen resultaat geeft. Heeft dat wellicht te maken met de startpositie?

Die wordt toch bepaald door

pic basic code:

 LCD_Setpos(0,0) 

?

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

De allereerste 0x40 na het startadres wordt als commando ontvangen. ("hierna komt data")
De volgende keer dat 0x40 wordt ontvangen wordt dat netjes als data behandeld en naar het display geschreven...
Daarom wordt de eerste 0x40 niet naar het display geschreven en alle volgende wel...

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

vergeef me.. ;(, maar ik vat het nog even niet.

pic basic code:

 for i1 = 1 to 32
    Lcd_WrDat(i1)
    LCD_WrDat(0x00)   'Als je er een spatie tussen wilt
    Delay_ms(1000)
  next i1

Eerst wordt 0x78 weggeschreven (Slave Adress)
Dan komt 0x40 (volgende byte is data)
Dan komt de eerste data %00000001 (i1 gaat van 1 tot 32).

maar deze toont hij dus niet.

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Het kan zijn dat de display kolommen bij '1' beginnen te tellen.
Ligt aan de displaymaker, van die kleine OLED display-tjes is bar weinig bekend op de prijs na... ;)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Dat zou heel goed kunnen, want bij de 0,96"versie toont hij wél de eerste.

Die dingen kosten inderdaad heel erg weinig. Hoe kunnen ze het er voor maken...
Maar wel reuze handig als je een schakeling hebt waarbij je wat zichtbaar wilt hebben.
Je kan ze op een printje kwijt en van alles en nog wat tonen.

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Als je het hele scherm wit maakt, kun je wel zien dat ze bar slecht zijn eigenlijk... ;)
(als je met een vergrootglas kijkt zie je al gauw 50...100 beschadigde pixels. Vooral aan de randen vaak 'gerafelde' pixels)

https://www.circuitsonline.net/forum/file/3874

[Bericht gewijzigd door Arco op maandag 23 december 2019 15:29:30 (12%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

om de eerste pixel te tonen moet je hiermee beginnen:

pic basic code:

LCD_Setpos(2,0)

Met 2 horizontaal dus.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Nou, dat valt hier eigenlijk reuze mee. Ik heb hem ook onder het vergrootglas gelegd en zie niet echt kapotte pixels.
(En dan is er ook nog een bureaulamp op gevallen... ;()

Ik kan er geen goede foto van maken; er lopen dan balken door het beeld en krijg geen focus.

Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Dan heb je geluk gehad (of de fabrikant heeft zijn leven gebeterd... ;) ).
Ik had ze van verschillende leveranciers, allemaal min of meer beschadigd...
(heb 1 keer gereclameerd, kreeg toen een vervanger die net zo rot was, dus dat was ook geen oplossing...)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Tja,
Deze was $3,63 bij 'tante Alie'.

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Maar hij doet het leuk. Verschillende fonten..

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Ik ben nog weer even aan het stoeien met een OLED display, 128 * 64

In het programma heb ik :

pic basic code:

'===============================================================================
Sub Procedure LCD_Fill(Dim pFill As Byte)     'Fill display with character pFill
'===============================================================================
  Dim lx, ly As Byte
  For ly = 0 To 7
  LCD_wrCmd(0xB0 + ly)
  LCD_wrCmd(0x01)
  LCD_wrCmd(0x10)
    For lx = 0 to 127
      Lcd_wrDat(pFill)
    Next lx
  Next ly
End Sub

Waar ik even mee zit: het commando

pic basic code:

 LCD_wrCmd(0x01) 

Dit veroorzaakt op de eerste kolom (segment0) op een aantal rijen (niet allemaal) op kolom 1 oplichtende pixels.

Daardoor krijg je een 'sliertje' in beeld.
Als ik het commando weglaat, gaat het goed.

Ik snap niet goed wat de bedoeling van dit commando was.

Daarnaast: uit de sheet haal ik dat er 8 Blokken (Pages) zijn en 128 Segmenten (kolommen).

Dan is ly 0 to 7 en lx 0 to 127 toch goed voor deze display?
(er stond nl 0 to 8 en 0 to 131).

Fouten zijn het bewijs dat je het probeert..
Bavelt

Golden Member

Ik heb inmiddels een "Gewone" SPI-OLed (dus geen TFT).
Met een SSD1306 chip.

Het dingetje heeft de volgende pinnen:

Ik ben er al achter dat D0 = SCK, D1 = SDO.
Ik maak gebruik van de uc PIC16F1847, deze heeft een SPI aan boord.
(SDO op LATB.2, SCK op LATB.4)
Voor D/C heb ik LATB.0 gekozen en CS LATB.1

Wat ik met de RES moet weet ik niet precies.
Maar het displaytje doet niks. Ik doe ongetwijfeld iets fout...

Het programma:

pic basic code:



Dim SSel         As sBit At LATB.1                              'Display select
    D_C          As sBit At LATB.0                              'Data/Command

const Char6x8 As Byte[570] = (       'Character table
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  ' sp
0x00, 0x00, 0x00, 0x2f, 0x00, 0x00,  ' !
0x00, 0x00, 0x07, 0x00, 0x07, 0x00,  ' "
0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14,  ' #
0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12,  ' $
0x00, 0x62, 0x64, 0x08, 0x13, 0x23,  ' %
0x00, 0x36, 0x49, 0x55, 0x22, 0x50,  ' &
0x00, 0x00, 0x05, 0x03, 0x00, 0x00,  ' '
0x00, 0x00, 0x1c, 0x22, 0x41, 0x00,  ' (
0x00, 0x00, 0x41, 0x22, 0x1c, 0x00,  ' )
0x00, 0x14, 0x08, 0x3E, 0x08, 0x14,  ' *
0x00, 0x08, 0x08, 0x3E, 0x08, 0x08,  ' +
0x00, 0x00, 0x00, 0xA0, 0x60, 0x00,  ' ,
0x00, 0x08, 0x08, 0x08, 0x08, 0x08,  ' -
0x00, 0x00, 0x60, 0x60, 0x00, 0x00,  ' .
0x00, 0x20, 0x10, 0x08, 0x04, 0x02,  ' /
0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E,  ' 0
0x00, 0x00, 0x42, 0x7F, 0x40, 0x00,  ' 1
0x00, 0x42, 0x61, 0x51, 0x49, 0x46,  ' 2
0x00, 0x21, 0x41, 0x45, 0x4B, 0x31,  ' 3
0x00, 0x18, 0x14, 0x12, 0x7F, 0x10,  ' 4
0x00, 0x27, 0x45, 0x45, 0x45, 0x39,  ' 5
0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30,  ' 6
0x00, 0x01, 0x71, 0x09, 0x05, 0x03,  ' 7
0x00, 0x36, 0x49, 0x49, 0x49, 0x36,  ' 8
0x00, 0x06, 0x49, 0x49, 0x29, 0x1E,  ' 9
0x00, 0x00, 0x36, 0x36, 0x00, 0x00,  ' :
0x00, 0x00, 0x56, 0x36, 0x00, 0x00,  ' ;
0x00, 0x08, 0x14, 0x22, 0x41, 0x00,  ' <
0x00, 0x14, 0x14, 0x14, 0x14, 0x14,  ' =
0x00, 0x00, 0x41, 0x22, 0x14, 0x08,  ' >
0x00, 0x02, 0x01, 0x51, 0x09, 0x06,  ' ?
0x00, 0x32, 0x49, 0x59, 0x51, 0x3E,  ' @
0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C,  ' A
0x00, 0x7F, 0x49, 0x49, 0x49, 0x36,  ' B
0x00, 0x3E, 0x41, 0x41, 0x41, 0x22,  ' C
0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C,  ' D
0x00, 0x7F, 0x49, 0x49, 0x49, 0x41,  ' E
0x00, 0x7F, 0x09, 0x09, 0x09, 0x01,  ' F
0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A,  ' G
0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F,  ' H
0x00, 0x00, 0x41, 0x7F, 0x41, 0x00,  ' I
0x00, 0x20, 0x40, 0x41, 0x3F, 0x01,  ' J
0x00, 0x7F, 0x08, 0x14, 0x22, 0x41,  ' K
0x00, 0x7F, 0x40, 0x40, 0x40, 0x40,  ' L
0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F,  ' M
0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F,  ' N
0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E,  ' O
0x00, 0x7F, 0x09, 0x09, 0x09, 0x06,  ' P
0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E,  ' Q
0x00, 0x7F, 0x09, 0x19, 0x29, 0x46,  ' R
0x00, 0x46, 0x49, 0x49, 0x49, 0x31,  ' S
0x00, 0x01, 0x01, 0x7F, 0x01, 0x01,  ' T
0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F,  ' U
0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F,  ' V
0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F,  ' W
0x00, 0x63, 0x14, 0x08, 0x14, 0x63,  ' X
0x00, 0x07, 0x08, 0x70, 0x08, 0x07,  ' Y
0x00, 0x61, 0x51, 0x49, 0x45, 0x43,  ' Z
0x00, 0x00, 0x7F, 0x41, 0x41, 0x00,  ' [
0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55,  ' \
0x00, 0x00, 0x41, 0x41, 0x7F, 0x00,  ' ]
0x00, 0x04, 0x02, 0x01, 0x02, 0x04,  ' ^
0x00, 0x40, 0x40, 0x40, 0x40, 0x40,  ' _
0x00, 0x00, 0x01, 0x02, 0x04, 0x00,  ' '
0x00, 0x20, 0x54, 0x54, 0x54, 0x78,  ' a
0x00, 0x7F, 0x48, 0x44, 0x44, 0x38,  ' b
0x00, 0x38, 0x44, 0x44, 0x44, 0x20,  ' c
0x00, 0x38, 0x44, 0x44, 0x48, 0x7F,  ' d
0x00, 0x38, 0x54, 0x54, 0x54, 0x18,  ' e
0x00, 0x08, 0x7E, 0x09, 0x01, 0x02,  ' f
0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C,  ' g
0x00, 0x7F, 0x08, 0x04, 0x04, 0x78,  ' h
0x00, 0x00, 0x44, 0x7D, 0x40, 0x00,  ' i
0x00, 0x40, 0x80, 0x84, 0x7D, 0x00,  ' j
0x00, 0x7F, 0x10, 0x28, 0x44, 0x00,  ' k
0x00, 0x00, 0x41, 0x7F, 0x40, 0x00,  ' l
0x00, 0x7C, 0x04, 0x18, 0x04, 0x78,  ' m
0x00, 0x7C, 0x08, 0x04, 0x04, 0x78,  ' n
0x00, 0x38, 0x44, 0x44, 0x44, 0x38,  ' o
0x00, 0xFC, 0x24, 0x24, 0x24, 0x18,  ' p
0x00, 0x18, 0x24, 0x24, 0x18, 0xFC,  ' q
0x00, 0x7C, 0x08, 0x04, 0x04, 0x08,  ' r
0x00, 0x48, 0x54, 0x54, 0x54, 0x20,  ' s
0x00, 0x04, 0x3F, 0x44, 0x40, 0x20,  ' t
0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C,  ' u
0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C,  ' v
0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C,  ' w
0x00, 0x44, 0x28, 0x10, 0x28, 0x44,  ' x
0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C,  ' y
0x00, 0x44, 0x64, 0x54, 0x4C, 0x44,  ' z
0x00, 0x10, 0x6C, 0x82, 0x00, 0x00,  ' {
0x00, 0x00, 0x00, 0xFE, 0x00, 0x00,  ' |
0x00, 0x00, 0x00, 0x82, 0x6C, 0x10,  ' }
0x14, 0x14, 0x14, 0x14, 0x14, 0x14)  ' horiz lines

'====================================================================================================
Sub Procedure Init_App()                         'Initialize
'====================================================================================================
  Dim lRet As Byte
  Delay_ms(100)
  ANSELB = 0                                                     'All Port B digital
  TRISB  = %11110100                                             'PortB.0, PortB.1  and B.3 Output
  OSCCON = %01111000                                             '16Mhz internal

  Spi1_Init_Advanced(_SPI_MASTER_OSC_DIV4,
                     _SPI_DATA_SAMPLE_MIDDLE,
                     _SPI_CLK_IDLE_HIGH,
                     _SPI_HIGH_2_LOW)
  Delay_ms(100)
End Sub

'====================================================================================================
Sub Procedure Lcd_WrCmd(Dim pCmd As Byte)                       'Write command to display
'====================================================================================================
  D_C = 0
  Spi1_Write(pCmd)
End Sub

'====================================================================================================
Sub Procedure Lcd_WrDat(Dim pDat As Byte)                       'Write data to display
'====================================================================================================
  Dim lCnt As Byte
  D_C = 1
  Spi1_Write(pDat)
End Sub

'====================================================================================================
Sub Procedure Lcd_SetPos(Dim px, py as Byte)                    'Set write position on display
'====================================================================================================
  delay_us(1)
  Lcd_WrCmd(0xB0 + py)
  Lcd_WrCmd((px  >> 4) Or 0x10)
  Lcd_WrCmd((px And 0x0F))
  delay_us(1)
End Sub

'====================================================================================================
Sub Procedure LCD_Fill(Dim pFill As Byte)                       'Fill display with character pFill
'====================================================================================================
  Dim lx, ly As Byte
  For ly = 0 To 8
    Lcd_WrCmd(0xB0+ly)
    Lcd_WrCmd(0x01)
    Lcd_WrCmd(0x10)
    For lx = 0 to 131
      Lcd_WrDat(pFill)
    Next lx
  Next ly
End Sub

'====================================================================================================
Sub Procedure Lcd_Char_6x8(Dim px, py, pchar As Byte)           'Write one character
'====================================================================================================
  Dim lIndex As Word
  Lcd_SetPos(px, py)
  lIndex = pChar - 0x20
  lIndex = (lIndex << 2) + (lIndex << 1)
  Lcd_WrDat(Char6x8[lIndex+0])
  Lcd_WrDat(Char6x8[lIndex+1])
  Lcd_WrDat(Char6x8[lIndex+2])
  Lcd_WrDat(Char6x8[lIndex+3])
  Lcd_WrDat(Char6x8[lIndex+4])
  Lcd_WrDat(Char6x8[lIndex+5])
End Sub

'====================================================================================================
Sub Procedure Lcd_String_6x8(Dim px, py As Byte, Dim ByRef pDisp As String) ' Write string
'====================================================================================================
  Dim lLen, lCnt As Byte
  lLen = Length(pDisp)
  For lCnt = 0 To (lLen-1)
    If px >= 124 Then px = 0 py = py+1 End If
    Lcd_Char_6x8(px, py, pDisp[lCnt])
    px = px + 6
  Next lCnt
End Sub

'====================================================================================================
Main:                                                           'Main program
'====================================================================================================
    Init_App()                   'Initialize
    SSel = 0
    delay_ms(500)
    SSEL = 1                     'Only for 0.96", for 1.3" remove it

    delay_ms(500)
    Lcd_WrCmd(0xAE)              'Turn OLED panel off
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0xA8)              'Multiplex ratio set to
    Lcd_WrCmd(0x3F)              '63
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0xD3)              'Display offset RAM counter
    Lcd_WrCmd(0x00)              'none
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0x40)              'Start line address
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0xA1)              'Set segment remap rotation to left
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0xC8)              'Common output scan direction
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0xDA)              'Common signals pad
    Lcd_WrCmd(0x12)              'value
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0x81)              'Contrast control
    Lcd_WrCmd(0xFF)              'value
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0xA4)
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0xA6)              'Normal display
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0xD5)              'Clock ratio:oscillator frequency
    Lcd_WrCmd(0x80)              'oooo:rrrr
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0x8D)
    Lcd_WrCmd(0x14)
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0x00)              'Set lower column address
    Lcd_WrCmd(0x10)              'Set higher column address
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0xD9)              '15 clocks, discharge 1 clock
    Lcd_WrCmd(0xF1)              'dddd:pppp
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0xDB)              'Common output voltage
    Lcd_WrCmd(0x40)              'level
    '--------------------------------------------------------------------------
    Lcd_WrCmd(0x20)              'Addressing mode
    Lcd_WrCmd(0x02)              'value
    '--------------------------------------------------------------------------
'    Lcd_WrCmd(0xA7)
    Lcd_Fill(0x00)
    Lcd_SetPos(0,0)
    '--------------------------------------------------------------------------
    Lcd_String_6x8(0,0,"Dit is een test van")
    Lcd_String_6x8(0,1,"een 128x64 pixel gra-")
    Lcd_String_6x8(0,2,"fisch OLED display.")
    Lcd_String_6x8(0,3,"Met 't 6x8 pixel font")
    Lcd_String_6x8(0,4,"gaat er heel wat in-")
    Lcd_String_6x8(0,5,"formatie op zo'n mini")
    Lcd_String_6x8(0,6,"scherm van 1.1x2.2cm")
    Lcd_String_6x8(0,7,"(en toch nog scherp!)")
    Lcd_WrCmd(0xAF)    'Turn OLED panel on
    delay_ms(500)

    SSel = 1

    While True Wend
    
End.
Fouten zijn het bewijs dat je het probeert..
Arco

Special Member

Ik heb nog nooit problemen met die displays gehad... (wel nooit met de 1847 gebruikt, want met zo weinig geheugen heeft 't weinig zin...)
Maar zou wel moeten werken. Reset pin moet hoog zijn.

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Bavelt

Golden Member

Tja, het geheurgen zal misschien niet erg groot zijn, maar 8K van deze 1847 is toch ook niet héél klein.

Als ik naar de Report View kijk, zit er nog ruimte voldoende met dit programaatje.

Fouten zijn het bewijs dat je het probeert..