​ ​ ​ ​ SSD1306 OLED Screen Help - Page 3
Page 3 of 3 FirstFirst 1 2 3
Results 21 to 30 of 30

Thread: SSD1306 OLED Screen Help

  1. #21
    Senior Member
    Join Date
    May 2013
    Location
    Ireland
    Posts
    265

    Default

    Thank you very much.

    I'll try that and report back

  2. #22
    Senior Member
    Join Date
    May 2013
    Location
    Ireland
    Posts
    265

    Default

    This is what i see on the screen at the moment with the current code below:

    128x32 Screen.PNG

    Code:
    ' 08OLED_128x64 writes strings to lcd
    #picaxe 08M2
    #no_data
    #terminal 38400
    
    'Display command constants
    Symbol TWI_BUFFER_LENGTH = 32 
    Symbol LCDWIDTH = 128
    Symbol LCDHEIGHT = 32
    Symbol SETCONTRAST =0x81
    Symbol DISPLAYALLON_RESUME =0xA4
    Symbol DISPLAYALLON =0xA5
    Symbol NORMALDISPLAY =0xA6
    Symbol INVERTDISPLAY =0xA7
    Symbol DISPLAYOFF =0xAE
    Symbol DISPLAYON =0xAF
    Symbol SETDISPLAYOFFSET =0xD3
    Symbol SETCOMPINS =0xDA
    Symbol SETVCOMDETECT =0xDB
    Symbol SETDISPLAYCLOCKDIV =0xD5
    Symbol SETPRECHARGE =0xD9
    Symbol SETMULTIPLEX =0xA8
    Symbol SETLOWColUMN =0x00
    Symbol SETHIGHColUMN =0x10
    Symbol SETSTARTLINE =0x40
    Symbol MEMORYMODE =0x20
    Symbol COLUMNADDR =0x21
    Symbol PAGEADDR =0x22
    Symbol COMSCANINC =0xC0
    Symbol COMSCANDEC =0xC8
    Symbol SEGREMAP =0xA0 | 1
    Symbol CHARGEPUMP =0x8D
    Symbol EXTERNALVCC =0x1
    Symbol SWITCHCAPVCC =0x2
    
    symbol RAM_base = 28 ' beginning of upper ram
    symbol A_addr = 0 ' beginning of upper case letters in eeprom
    symbol N_addr = 130 ' beginning numbers in of upper eeprom
    Symbol I2CSpeed = i2cfast_32
    Symbol Display = $78 '       $3C << 1  '[$78]
    
    'Byte variables
    ' symbol xb0 = b0 ' used to hold ascii charactor to be written
    ' symbol xb1 = b1 ' index into string to be written
    ' symbol xb2 = b2 ' used in ClearDisplay
    Symbol ch     = b4
    Symbol i      = b5
    Symbol row    = b6
    Symbol col    = b7
    symbol eeAdr = b8
    
      setfreq m32
      read A_addr,ch
      i = 0x7C ' first of 5 bytes defining pixel pattern for "A"
      if ch <> i then ' eeprom not established
        gosub writeEEPROM
      endif
    
      hi2csetup i2cmaster, Display, I2CSpeed, I2cbyte   'Need to initialise I2C 
      gosub InitDisplay
      gosub ClearDisplay
      sertxd("08OLED_128x64",cr,lf)
      pause 5000
      row = 0 : col = 0 : gosub SetPosition
    '  b1 = 0 : do : LookUp b1, ( "0123456789",0 ), b0 
      b1 = 0 : do : LookUp b1, ( "HELLO WORLD",0 ), b0 
        if b0 <> 0 then : Gosub ShowChar : endif : inc b1
      loop until b0 = 0
      sertxd(cr,lf)
    '#rem
      for row = 1 to 7
        col = 0
        sertxd(#row,"/",#col," ")
        gosub SetPosition
        b1 = 0 : do : LookUp b1, ( "LINE ",0 ), b0 
          if b0 <> 0 then : Gosub ShowChar : endif : inc b1
        loop until b0 = 0
        b0 = row + "0" ' display line number
        Gosub ShowChar
        sertxd(cr,lf)
    '    pause 32000
      next row
      b1 = 0 : do : LookUp b1, ( " 0123456789",0 ), b0 
        if b0 <> 0 then : Gosub ShowChar : endif : inc b1
      loop until b0 = 0
      sertxd(cr,lf)
    '#endrem
      do : loop
      end
    
    ShowChar: ' A-Z, 0-9, space
      sertxd(b0)
      if b0 >= "A" and b0 <= "Z" then
        bptr = RAM_base ' base of upper ram 
        eeAdr = b0 - "A" * 5 + A_addr ' point to 5 unique char bytes in eeprom
        read eeAdr,@bptrinc, @bptrinc, @bptrinc, @bptrinc, @bptrinc ' move from eeprom to ram
        bptr = RAM_base ' base of upper ram 
        hi2cout (0x40, @bptrinc, @bptrinc, @bptrinc, @bptrinc, @bptrinc, 0)
      elseif b0 >= "0" and b0 <= "9" then
        bptr = RAM_base ' base of upper ram 
        eeAdr = b0 - "0" * 5 + N_addr ' point to 5 unique char bytes in eeprom
        read eeAdr,@bptrinc, @bptrinc, @bptrinc, @bptrinc, @bptrinc ' move from eeprom to ram
        bptr = RAM_base ' base of upper ram 
        hi2cout (0x40, @bptrinc, @bptrinc, @bptrinc, @bptrinc, @bptrinc, 0)
      elseif b0 = " " then
        hi2cout (0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0)
      endif
      return
    
    ' code below by edmonds: http://www.picaxeforum.co.uk/showthread.php?27651-I2C-OLED-display
      InitDisplay:
      hi2cout (0, DISPLAYOFF)
      hi2cout (0, SETDISPLAYCLOCKDIV)
      hi2cout (0, 0x80)
      hi2cout (0, SETMULTIPLEX)
      hi2cout (0, 0x3F)
      hi2cout (0, SETDISPLAYOFFSET)
      hi2cout (0, 0x0)
      hi2cout (0, SETSTARTLINE)
      hi2cout (0, CHARGEPUMP)
      hi2cout (0, 0x14)
      hi2cout (0, MEMORYMODE)
      hi2cout (0, 0x00)
      hi2cout (0, SEGREMAP)
      hi2cout (0, COMSCANDEC)
      hi2cout (0, SETCOMPINS)
      hi2cout (0, 0x12)
      hi2cout (0, SETCONTRAST)
      hi2cout (0, 0xCF)
      hi2cout (0, SETPRECHARGE)
      hi2cout (0, 0xF1)
      hi2cout (0, SETVCOMDETECT)
      hi2cout (0, 0x40)
      hi2cout (0, DISPLAYALLON_RESUME)
      hi2cout (0, DISPLAYON)
    return
    
    SetPosition:
      hi2cout (0, PAGEADDR)
      hi2cout (0, row)
      hi2cout (0, 7)
    
      hi2cout (0, COLUMNADDR)
    ;  col = col * 5 'columns per character   -   !!! NB not sure what this does or does not !!!
      hi2cout (0, col)
      hi2cout (0, 127)
    
    return
    
    ClearDisplay:
    
      for b2 = 0 to LCDWIDTH
        hi2cout (0x40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
      next b2
    
      hi2cout (0, COLUMNADDR)
      hi2cout (0, 0)
      hi2cout (0, 127)
      hi2cout (0, PAGEADDR)
      hi2cout (0, 0)
      hi2cout (0, 7)
      
    return
    
    writeEEPROM:
        pause 32000
        sertxd("invalid check char: ",#ch," not ",0x7c,"; writing eeprom",cr,lf)
        write A_addr, _
                0x7C, 0x12, 0x11, 0x12, 0x7C, 0x7F, 0x49, 0x49, 0x49, 0x36, _
                0x3E, 0x41, 0x41, 0x41, 0x22, 0x7F, 0x41, 0x41, 0x41, 0x3E, _
                0x7F, 0x49, 0x49, 0x49, 0x41, 0x7F, 0x09, 0x09, 0x09, 0x01, _
                0x3E, 0x41, 0x41, 0x51, 0x73, 0x7F, 0x08, 0x08, 0x08, 0x7F, _
                0x00, 0x41, 0x7F, 0x41, 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01, _
                0x7F, 0x08, 0x14, 0x22, 0x41, 0x7F, 0x40, 0x40, 0x40, 0x40, _
                0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x7F, 0x04, 0x08, 0x10, 0x7F, _
                0x3E, 0x41, 0x41, 0x41, 0x3E, 0x7F, 0x09, 0x09, 0x09, 0x06, _
                0x3E, 0x41, 0x51, 0x21, 0x5E, 0x7F, 0x09, 0x19, 0x29, 0x46, _
                0x26, 0x49, 0x49, 0x49, 0x32, 0x03, 0x01, 0x7F, 0x01, 0x03, _
                0x3F, 0x40, 0x40, 0x40, 0x3F, 0x1F, 0x20, 0x40, 0x20, 0x1F, _
                0x3F, 0x40, 0x38, 0x40, 0x3F, 0x63, 0x14, 0x08, 0x14, 0x63, _
                0x03, 0x04, 0x78, 0x04, 0x03, 0x61, 0x59, 0x49, 0x4D, 0x43
    ' above are 5-byte codes for ABCDEFGHIJKLMNOPQRSTUVWXYZ
        pause 160
        write N_addr, _
                0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, 0x42, 0x7F, 0x40, 0x00, _
                0x72, 0x49, 0x49, 0x49, 0x46, 0x21, 0x41, 0x49, 0x4D, 0x33, _
                0x18, 0x14, 0x12, 0x7F, 0x10, 0x27, 0x45, 0x45, 0x45, 0x39, _
                0x3C, 0x4A, 0x49, 0x49, 0x31, 0x41, 0x21, 0x11, 0x09, 0x07, _
                0x36, 0x49, 0x49, 0x49, 0x36, 0x46, 0x49, 0x49, 0x29, 0x1E
    ' above are 5-byte codes for 0123456789
        pause 160
      return

  3. #23
    Senior Member
    Join Date
    May 2013
    Location
    Ireland
    Posts
    265

    Default

    I have been trying to play around with the example code and to be honest i am struggling.

    Is there a simplified code somewhere just to write numbers in the middle of the screen?

    What lines of the existing code are responsible for the font side?

    For my current project i only really want to display possible one single word and a 2 digit number, or even just the number in the middle of the screen.

    Thanks very much in advance.

  4. #24
    Senior Member
    Join Date
    May 2013
    Location
    Ireland
    Posts
    265

    Default

    I managed to figure out some of the code but not enough to make the letters display fully.

    All letters are cut off at the top and bottom.

    The line of text on the screen is THIS IS A TEST.

    There is something funny going on.

    Any idea on how to fix it and possibly make it larger at the same time?

    Thank you.

    128x32 Screen_1.JPG


    Code:
    ' 08OLED_128x64 writes strings to lcd
    #picaxe 08M2
    #no_data
    #terminal 38400
    
    'Display command constants
    Symbol TWI_BUFFER_LENGTH = 32 
    Symbol LCDWIDTH = 128
    Symbol LCDHEIGHT = 32
    Symbol SETCONTRAST =0x81
    Symbol DISPLAYALLON_RESUME =0xA4
    Symbol DISPLAYALLON =0xA5
    Symbol NORMALDISPLAY =0xA6
    Symbol INVERTDISPLAY =0xA7
    Symbol DISPLAYOFF =0xAE
    Symbol DISPLAYON =0xAF
    Symbol SETDISPLAYOFFSET =0xD3
    Symbol SETCOMPINS =0xDA
    Symbol SETVCOMDETECT =0xDB
    Symbol SETDISPLAYCLOCKDIV =0xD5
    Symbol SETPRECHARGE =0xD9
    Symbol SETMULTIPLEX =0xA8
    Symbol SETLOWColUMN =0x00
    Symbol SETHIGHColUMN =0x10
    Symbol SETSTARTLINE =0x40
    Symbol MEMORYMODE =0x20
    Symbol COLUMNADDR =0x21
    Symbol PAGEADDR =0x22
    Symbol COMSCANINC =0xC0
    Symbol COMSCANDEC =0xC8
    Symbol SEGREMAP =0xA0 | 1
    Symbol CHARGEPUMP =0x8D
    Symbol EXTERNALVCC =0x1
    Symbol SWITCHCAPVCC =0x2
    
    symbol RAM_base = 28 ' beginning of upper ram
    symbol A_addr = 0 ' beginning of upper case letters in eeprom
    symbol N_addr = 130 ' beginning numbers in of upper eeprom
    Symbol I2CSpeed = i2cfast_32
    Symbol Display = $78 '       $3C << 1  '[$78]
    
    'Byte variables
    ' symbol xb0 = b0 ' used to hold ascii charactor to be written
    ' symbol xb1 = b1 ' index into string to be written
    ' symbol xb2 = b2 ' used in ClearDisplay
    Symbol ch     = b4
    Symbol i      = b5
    Symbol row    = b6
    Symbol col    = b7
    symbol eeAdr = b8
    
      setfreq m32
      read A_addr,ch
      i = 0x7C ' first of 5 bytes defining pixel pattern for "A"
      if ch <> i then ' eeprom not established
        gosub writeEEPROM
      endif
    
      hi2csetup i2cmaster, Display, I2CSpeed, I2cbyte   'Need to initialise I2C 
      gosub InitDisplay
      gosub ClearDisplay
      sertxd("08OLED_128x32",cr,lf)
      pause 5000
      row = 20 : col = 20 : gosub SetPosition
    'b1 = 0 : do : LookUp b1, ( "0123456789",0 ), b0 
      b1 = 0 : do : LookUp b1, ( "THIS IS A TEST",0 ), b0 
        if b0 <> 0 then : Gosub ShowChar : endif : inc b1
      loop until b0 = 0
      sertxd(cr,lf)
    #rem
      for row = 1 to 7
        col = 0
        sertxd(#row,"/",#col," ")
        gosub SetPosition
        b1 = 0 : do : LookUp b1, ( "LINE ",0 ), b0 
          if b0 <> 0 then : Gosub ShowChar : endif : inc b1
        loop until b0 = 0
        b0 = row + "0" ' display line number
        Gosub ShowChar
        sertxd(cr,lf)
    '    pause 32000
      next row
      b1 = 0 : do : LookUp b1, ( " 0123456789",0 ), b0 
        if b0 <> 0 then : Gosub ShowChar : endif : inc b1
      loop until b0 = 0
      sertxd(cr,lf)
    #endrem
      do : loop
      end
    
    ShowChar: ' A-Z, 0-9, space
      sertxd(b0)
      if b0 >= "A" and b0 <= "Z" then
        bptr = RAM_base ' base of upper ram 
        eeAdr = b0 - "A" * 5 + A_addr ' point to 5 unique char bytes in eeprom
        read eeAdr,@bptrinc, @bptrinc, @bptrinc, @bptrinc, @bptrinc ' move from eeprom to ram
        bptr = RAM_base ' base of upper ram 
        hi2cout (0x40, @bptrinc, @bptrinc, @bptrinc, @bptrinc, @bptrinc, 0)
      elseif b0 >= "0" and b0 <= "9" then
        bptr = RAM_base ' base of upper ram 
        eeAdr = b0 - "0" * 5 + N_addr ' point to 5 unique char bytes in eeprom
        read eeAdr,@bptrinc, @bptrinc, @bptrinc, @bptrinc, @bptrinc ' move from eeprom to ram
        bptr = RAM_base ' base of upper ram 
        hi2cout (0x40, @bptrinc, @bptrinc, @bptrinc, @bptrinc, @bptrinc, 0)
      elseif b0 = " " then
        hi2cout (0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0)
      endif
      return
    
    ' code below by edmonds: http://www.picaxeforum.co.uk/showthread.php?27651-I2C-OLED-display
      InitDisplay:
      hi2cout (0, DISPLAYOFF)
      hi2cout (0, SETDISPLAYCLOCKDIV)
      hi2cout (0, 0x80)
      hi2cout (0, SETMULTIPLEX)
      hi2cout (0, 0x3F)
      hi2cout (0, SETDISPLAYOFFSET)
      hi2cout (0, 0x0)
      hi2cout (0, SETSTARTLINE)
      hi2cout (0, CHARGEPUMP)
      hi2cout (0, 0x14)
      hi2cout (0, MEMORYMODE)
      hi2cout (0, 0x00)
      hi2cout (0, SEGREMAP)
      hi2cout (0, COMSCANDEC)
      hi2cout (0, SETCOMPINS)
      hi2cout (0, 0x12)
      hi2cout (0, SETCONTRAST)
      hi2cout (0, 0xCF)
      hi2cout (0, SETPRECHARGE)
      hi2cout (0, 0xF1)
      hi2cout (0, SETVCOMDETECT)
      hi2cout (0, 0x40)
      hi2cout (0, DISPLAYALLON_RESUME)
      hi2cout (0, DISPLAYON)
    return
    
    SetPosition:
      hi2cout (0, PAGEADDR)
      hi2cout (0, row)
      hi2cout (0, 7)
    
      hi2cout (0, COLUMNADDR)
    ;  col = col * 5 'columns per character   -   !!! NB not sure what this does or does not !!!
      hi2cout (0, col)
      hi2cout (0, 127)
    
    return
    
    ClearDisplay:
    
      for b2 = 0 to LCDWIDTH
        hi2cout (0x40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
      next b2
    
      hi2cout (0, COLUMNADDR)
      hi2cout (0, 0)
      hi2cout (0, 127)
      hi2cout (0, PAGEADDR)
      hi2cout (0, 0)
      hi2cout (0, 7)
      
    return
    
    writeEEPROM:
        pause 32000
        sertxd("invalid check char: ",#ch," not ",0x7c,"; writing eeprom",cr,lf)
        write A_addr, _
                0x7C, 0x12, 0x11, 0x12, 0x7C, 0x7F, 0x49, 0x49, 0x49, 0x36, _
                0x3E, 0x41, 0x41, 0x41, 0x22, 0x7F, 0x41, 0x41, 0x41, 0x3E, _
                0x7F, 0x49, 0x49, 0x49, 0x41, 0x7F, 0x09, 0x09, 0x09, 0x01, _
                0x3E, 0x41, 0x41, 0x51, 0x73, 0x7F, 0x08, 0x08, 0x08, 0x7F, _
                0x00, 0x41, 0x7F, 0x41, 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01, _
                0x7F, 0x08, 0x14, 0x22, 0x41, 0x7F, 0x40, 0x40, 0x40, 0x40, _
                0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x7F, 0x04, 0x08, 0x10, 0x7F, _
                0x3E, 0x41, 0x41, 0x41, 0x3E, 0x7F, 0x09, 0x09, 0x09, 0x06, _
                0x3E, 0x41, 0x51, 0x21, 0x5E, 0x7F, 0x09, 0x19, 0x29, 0x46, _
                0x26, 0x49, 0x49, 0x49, 0x32, 0x03, 0x01, 0x7F, 0x01, 0x03, _
                0x3F, 0x40, 0x40, 0x40, 0x3F, 0x1F, 0x20, 0x40, 0x20, 0x1F, _
                0x3F, 0x40, 0x38, 0x40, 0x3F, 0x63, 0x14, 0x08, 0x14, 0x63, _
                0x03, 0x04, 0x78, 0x04, 0x03, 0x61, 0x59, 0x49, 0x4D, 0x43
    ' above are 5-byte codes for ABCDEFGHIJKLMNOPQRSTUVWXYZ
        pause 160
        write N_addr, _
                0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00, 0x42, 0x7F, 0x40, 0x00, _
                0x72, 0x49, 0x49, 0x49, 0x46, 0x21, 0x41, 0x49, 0x4D, 0x33, _
                0x18, 0x14, 0x12, 0x7F, 0x10, 0x27, 0x45, 0x45, 0x45, 0x39, _
                0x3C, 0x4A, 0x49, 0x49, 0x31, 0x41, 0x21, 0x11, 0x09, 0x07, _
                0x36, 0x49, 0x49, 0x49, 0x36, 0x46, 0x49, 0x49, 0x29, 0x1E
    ' above are 5-byte codes for 0123456789
        pause 160
      return

  5. #25
    Technical Support
    Join Date
    Jan 1970
    Location
    UK
    Posts
    24,365

    Default

    OLED graphic displays are complicated to work with. One needs to know exactly what model of display one has, what the screen memory mapping is, the command set and configuration used. That does vary between models from the same manufacturer, for example, not all SSD displays are the same.

    It can be quite a struggle getting things right. The best advice is to start with displaying a single vertical line of pixels at the top left, then bottom right, enhancing those two two and more vertical lines of pixels.

    Set the location being written to before every byte to start with, just in case auto-location incrementing isn't exactly how you want it to be. That can be removed later.

    Once it comes to full character display start with single characters top left, bottom right. Displaying "F" and "9" can help ensure that what's being shown is as should be shown.

    Diving in with something 'in the middle' is probably going to make things complicated. Your middle might not be what the display has as middle. You may be crossing 'sets of 8 pixel' boundaries and causing odd things to happen. Start with top character line, then next character line.

    Although a display may be 128x32 it is probably best to think of it as 21x4 characters, each character 6x8.

    Making characters bigger, wider, then taller and then both, should be the last thing to do. That's a case of double writing to make wider, splitting pixels and doubling them up to write across two lines to be taller.

  6. #26
    Senior Member
    Join Date
    Jan 1970
    Location
    Nova Scotia, Canada
    Posts
    2,829

    Default

    It looks like the display is acting like it's being told that it has 8 rows of characters, so it's truncating the 8-pixel deep character map to fit into the 4 pixels per row that you have if you divided 32 pixels deep by 8.

    I don't know what in the initialization is causing that, and without a datasheet it's hard to guess.

    It might have to do with the MEMORYMODE setting. Or in SetPosition you might change (0, 7) to (0, 3). This may be completely wrong.

    Also, I would not set "row = 20". It looks to me like the "row" variable is not pixel-oriented (as col is), but it somehow knows how many pixels deep a "row" is. To test, program with "row = 1", "row = 5", etc. to see exactly where the line shows up.

    As hippy says, changing the size of the characters will be non-trivial. The font is for a specific 5-wide by 7-deep pixel map per character. You might find something by searching which defines other fonts, but the codes would have to be brought into PICAXE format, as well as the initialization values, as Edmonds did in the post you originally linked to. You might also be able to find non-PICAXE programs which use the 128x32 display, and find clues there.

    I won't be able to provide much assistance before Monday--building a boathouse this weekend.

  7. #27
    Technical Support
    Join Date
    Jan 1970
    Location
    UK
    Posts
    24,365

    Default

    Quote Originally Posted by lbenson View Post
    As hippy says, changing the size of the characters will be non-trivial. The font is for a specific 5-wide by 7-deep pixel map per character.
    That's not too hard; for widening it's just write the vertical pixel row twice.

    For doubling height, assuming the 8-pixel vertical row is held in 'b0', top pixel in 'bit0' ...

    Code:
    bit15 = bit7 : bit14 = bit7
    bit13 = bit6 : bit12 = bit6
    bit11 = bit5 : bit10 = bit5
    bit9  = bit4 : bit8  = bit4
    bit7  = bit3 : bit6  = bit3
    bit5  = bit2 : bit4  = bit2
    bit3  = bit1 : bit2  = bit1
    bit1  = bit0
    Then write 'b0' to the top line row, 'b1' to the line below it.

    For doubling height and widening just double as above then write 'b0' and 'b1' twice.

  8. #28
    Senior Member
    Join Date
    Jan 1970
    Location
    Nova Scotia, Canada
    Posts
    2,829

    Default

    In the adafruit c++ library, the only difference I see in initialization other than LCDHEIGHT = 32 is that the value following the SETCOMPINS line is 0x2 instead of 0x12. In the SetPosition routine, the line after "hi2cout (0, row)" is "hi2cout (0, 3)", not 7.

    Try those changes and let us know what you see.

  9. #29
    Senior Member
    Join Date
    May 2013
    Location
    Ireland
    Posts
    265

    Default

    Thanks very much guys.

    I'll keep at it.

    thanks very much for all the help.

    much appreciated.

  10. #30

Bookmarks

Posting Permissions

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