Share My Creation OLED Picture Frame

OLED 0.95", SSD1331, 96x64 display driven by Arduino Uno or Nano to display pictures from SD card. The SD is interfaced by the main ATMEGA ISP and the Oled interfaced by USART as ISP. The code reads the SD 96 bytes at a time and streams them to the Oled. Inline C is used to set up the USART ISP, the code also initialize the Oled.
1K resistors are to reduce 5V outputs of Arduino to 3.3V Oled input.
To setup the SD:
Format the card with FAT32.
Create image file using MS Paint or another program, image size 64 pixels high by 96 pixels wide.
Name the files "1.bmp", "2.bmp", etc.
Save the files as 24 bits bmp.
Convert bitmap to 16 bit BMP file, 5:6:5 top to bottom. I used the online converter: https://online-converting.com/image/convert2bmp/
Add the files to the root folder of the card (don't use a directory).
B4X:
Sub Process_Globals
    Private sd As SD
    'Public Serial1 As Serial
    Public CSled, CSsd As Pin
    Public DC As Pin
    Public SDA As Pin
    Public SCK, SCKsd As Pin
    Public RST As Pin
    Private miso, mosi As Pin
    Private spires, spidata As Byte

End Sub

Private Sub AppStart
    'Serial1.Initialize(9600)
    sd.Initialize(10) '10 is the CS pin

    CSled.Initialize(7, CSled.MODE_OUTPUT)
    DC.Initialize(9, DC.MODE_OUTPUT)    'AO
    RST.Initialize(8, RST.MODE_OUTPUT)
    SDA.Initialize(1, SDA.MODE_OUTPUT)    'MOSI
    SCK.Initialize(4, SCK.MODE_OUTPUT)
 
    mosi.Initialize(11, mosi.MODE_OUTPUT)    'MOSI
    SCKsd.Initialize(13, SCKsd.MODE_OUTPUT)
    CSsd.Initialize(10, CSsd.MODE_OUTPUT)
    miso.Initialize(12, miso.MODE_INPUT)
 
    RunNative ("set_spi",Null)
    oled_init
    getBMP

End Sub


Sub getBMP
    Do While True
        sd.OpenRead("1.bmp")
        If sd.Exists("1.bmp") Then
            display
            Delay(10000)
        End If
        sd.OpenRead("2.bmp")
        If sd.Exists("2.bmp") Then
            display
            Delay(10000)
        End If
        sd.OpenRead("3.bmp")
        If sd.Exists("3.bmp") Then
            display
            Delay(10000)
        End If
        sd.OpenRead("4.bmp")
        If sd.Exists("4.bmp") Then
            display
            Delay(10000)
        End If
     
        sd.OpenRead("5.bmp")
        If sd.Exists("5.bmp") Then
            display
            Delay(10000)
        End If
        sd.OpenRead("6.bmp")
        If sd.Exists("6.bmp") Then
            display
            Delay(10000)
        End If
    Loop
End Sub

Sub display
    Dim j As Byte
    Dim i As Byte 'ULong
    Dim buf1(96) As Byte
 
    command(0x15)    ' Column addr set
    command(0)
    command(95)
    command(0x75)    ' row addr set
    command(0)
    command(63)
 
    For i=0 To 127    'file=12,354 bytes
        If i=127 Then sd.Position=i*96+65 Else sd.Position=i*96+67
        sd.Stream.ReadBytes(buf1,0,96)
        For j=0 To 95
            send_data(buf1(j))
        Next
    Next

End Sub

Sub oled_init
    RST.DigitalWrite(True)    'hardware reset
    Delay(200)
    RST.DigitalWrite(False)
    Delay(10)
    RST.DigitalWrite(True)
    Delay(10)
    command(0xAE) 'display off

    command(0xA0) 'remap
    command(0x72) 'RGB=0x72, BGR=0x76

    command(0xA1) ' CMD STARTLINE
    command(0x0)
    command(0xA2)' CMD DISPLAYOFFSET
    command(0x0)
    command(0xA4)' CMD NORMALDISPLAY
    command(0xA8)' CMD SETMULTIPLEX
    command(0x3F)  ' 0x3F 1/64 duty
    command(0xAD)' CMD SETMASTER
    command(0x8E)
    command(0xB0)' CMD POWERMODE
    command(0x0B)
    command(0xB1)' CMD PRECHARGE
    command(0x31)
    command(0xB3)' CMD CLOCKDIV
    command(0xF0)' 7:4 = Oscillator Frequency, 3:0 = CLK Div Ratio
    ' (A[3:0]+1 = 1..16)
 
    command(0x8A)' CMD PRECHARGEA
    command(0x64)
    command(0x8B)' CMD PRECHARGEB
    command(0x78)
    command(0x8C)' CMD PRECHARGEC
    command(0x64)
    command(0xBB)' CMD PRECHARGELEVEL
    command(0x3A)
    command(0xBE)' CMD VCOMH
    command(0x3E)
    command(0x87)' CMD MASTERCURRENT 6
    command(0x01)
 
    command(0x81)' CMD CONTRASTA 91
    command(0xFF)
    command(0x82)' CMD CONTRASTB 50
    command(0xFF)
    command(0x83)' CMD CONTRASTC 7D
    command(0xFF)

    '  command(0xA4)'Normal display on
    command(0xAF)'Main screen turn on
End Sub


Sub spi(data As Byte)    'send byte over spi
    spidata=data
    RunNative ("spi",Null)
    Return
End Sub

Sub command(cmd As Byte)
    DC.DigitalWrite(False)    'command Mode
    CSled.DigitalWrite(False)    'Select the LCD (active low)
      spi(cmd)'set up data on bus
      CSled.DigitalWrite(True)    'Deselect LCD (active low)
End Sub

Sub send_data(data As Byte)
    DC.DigitalWrite(True)    'data mode
    CSled.DigitalWrite(False)    'Select the LCD (active low)
    spi(data)    'set up data on bus
    CSled.DigitalWrite(True)    'Deselect LCD (active low)
End Sub


    #if C
    void spi(B4R::Object* o)
    {
        while ( !( UCSR0A & (1<<UDRE0)) );    // Wait for empty transmit buffer
        UDR0 = b4r_main::_spidata;        // Put data into buffer, sends the data
        while ( !(UCSR0A & (1<<RXC0)) );        // Wait for data to be received
        b4r_main::_spires = UDR0;    // return received data from buffer
    }

    void set_spi(B4R::Object* o)
    {
        UBRR0 = 0;
        UCSR0C = (1<<UMSEL01)|(1<<UMSEL00)|(1<<UCPHA0)|(1<<UCPOL0); // MSPI mode and SPI data mode 3
        UCSR0B = (1<<RXEN0)|(1<<TXEN0);        // Enable receiver and transmitter
        UBRR0 = 8;    // Set baud rate. must be at the end
    }
    #End if
 

Attachments

  • oled1331_picture_frame.zip
    2.2 KB · Views: 275
  • bmp.zip
    9.1 KB · Views: 287
  • oled1331-400.jpg
    oled1331-400.jpg
    44.3 KB · Views: 2,126
  • oled_picture_frame.gif
    oled_picture_frame.gif
    6.2 KB · Views: 295
Last edited:
Top