Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 7 of 7

Thread: OLED problems

  1. #1
    Member
    Join Date
    Sep 2019
    Location
    Sevilla, Spain
    Posts
    66

    OLED problems

    Hi there, I'm having some issues with a cheap OLED display, SH1106 128 x 64 pixels,
    I thought that it was a faulty part but I tested with another one and got the same result.
    I've try with several OLED libraries, some of them work on the upper row of the display and the rest shows snow,
    the only one that can draw the whole display is <U8g2lib.h> but it takes a very long time (about 37 ms) to send the buffer.
    Please any advice about this would be much appreciated.

    my pins on the Teensy are:

    #define OLED_CLK 0
    #define OLED_MOSI 9
    #define OLED_RESET 27
    #define OLED_DC 26
    #define OLED_CS 1

    those pins are not shared with other SPI devices
    the pcb circuit is:
    Click image for larger version. 

Name:	Captura de pantalla 2021-09-13 a las 14.27.07.png 
Views:	17 
Size:	20.0 KB 
ID:	25837

  2. #2
    Senior Member PaulS's Avatar
    Join Date
    Apr 2015
    Location
    Netherlands
    Posts
    659
    Not all SH1106 libraries are created equally...did you perhaps try this one?
    It seems to be working fine for forum member 'frohr' using an SH1106 display. See this thread.

    Paul

  3. #3
    Member
    Join Date
    Sep 2019
    Location
    Sevilla, Spain
    Posts
    66
    Quote Originally Posted by PaulS View Post
    Not all SH1106 libraries are created equally...did you perhaps try this one?
    It seems to be working fine for forum member 'frohr' using an SH1106 display. See this thread.

    Paul
    Thx Paul,
    I get some errors compiling for Teensy 4.0,
    Code:
    /Users/jesus/Documents/Arduino/libraries/Adafruit_SH1106-master/Adafruit_SH1106.cpp: In member function 'void Adafruit_SH1106::begin(uint8_t, uint8_t, bool)':
    /Users/jesus/Documents/Arduino/libraries/Adafruit_SH1106-master/Adafruit_SH1106.cpp:179:17: error: cannot convert 'volatile uint32_t* {aka volatile long unsigned int*}' to 'PortReg* {aka volatile unsigned char*}' in assignment
         csport      = portOutputRegister(digitalPinToPort(cs));
                     ^
    /Users/jesus/Documents/Arduino/libraries/Adafruit_SH1106-master/Adafruit_SH1106.cpp:181:17: error: cannot convert 'volatile uint32_t* {aka volatile long unsigned int*}' to 'PortReg* {aka volatile unsigned char*}' in assignment
         dcport      = portOutputRegister(digitalPinToPort(dc));
                     ^
    /Users/jesus/Documents/Arduino/libraries/Adafruit_SH1106-master/Adafruit_SH1106.cpp:187:19: error: cannot convert 'volatile uint32_t* {aka volatile long unsigned int*}' to 'PortReg* {aka volatile unsigned char*}' in assignment
           clkport     = portOutputRegister(digitalPinToPort(sclk));
                       ^
    /Users/jesus/Documents/Arduino/libraries/Adafruit_SH1106-master/Adafruit_SH1106.cpp:189:19: error: cannot convert 'volatile uint32_t* {aka volatile long unsigned int*}' to 'PortReg* {aka volatile unsigned char*}' in assignment
           mosiport    = portOutputRegister(digitalPinToPort(sid));
                       ^
    Error compiling for board Teensy 4.0.

  4. #4
    Senior Member PaulS's Avatar
    Join Date
    Apr 2015
    Location
    Netherlands
    Posts
    659
    Hmm, got the same compilation error when trying to compile the example sh1106_128x64_spi.ino that came with library.

    Since the maker of the library stated on his Github page that his library was a modification of Adafruit's SSD1306 library, I compared the Adafruit_SSD1306.h and Adafruit_SH1106.h files.
    I noticed this difference within the .h files: (it's related to the errors)
    Adafruit_SH1106.h:
    Code:
    #ifdef __SAM3X8E__
     typedef volatile RwReg PortReg;
     typedef uint32_t PortMask;
    #else
      typedef volatile uint8_t PortReg;
      typedef uint8_t PortMask;
    #endif
    Adafruit_SSD1306.h:
    Code:
    #if defined(__AVR__)
    typedef volatile uint8_t PortReg;
    typedef uint8_t PortMask;
    #define HAVE_PORTREG
    #elif defined(__SAM3X8E__)
    typedef volatile RwReg PortReg;
    typedef uint32_t PortMask;
    #define HAVE_PORTREG
    #elif (defined(__arm__) || defined(ARDUINO_FEATHER52)) &&                      \
        !defined(ARDUINO_ARCH_MBED) && !defined(ARDUINO_ARCH_RP2040)
    typedef volatile uint32_t PortReg;
    typedef uint32_t PortMask;
    #define HAVE_PORTREG
    #endif
    So I modified Adafruit_SH1106.h to look like this:
    Code:
    /*********************************************************************
    This is a library for our Monochrome OLEDs based on SSD1306 drivers
    
      Pick one up today in the adafruit shop!
      ------> http://www.adafruit.com/category/63_98
    
    These displays use SPI to communicate, 4 or 5 pins are required to  
    interface
    
    Adafruit invests time and resources providing this open source code, 
    please support Adafruit and open-source hardware by purchasing 
    products from Adafruit!
    
    Written by Limor Fried/Ladyada  for Adafruit Industries.  
    BSD license, check license.txt for more information
    All text above, and the splash screen must be included in any redistribution
    *********************************************************************/
    
    /*********************************************************************
    I change the adafruit SSD1306 to SH1106
    
    SH1106 driver similar to SSD1306 so, just change the display() method.
    
    However, SH1106 driver don't provide several functions such as scroll commands.
    
    
    *********************************************************************/
    
    #if ARDUINO >= 100
     #include "Arduino.h"
     #define WIRE_WRITE Wire.write
    #else
     #include "WProgram.h"
      #define WIRE_WRITE Wire.send
    #endif
    
    // #ifdef __SAM3X8E__
    //  typedef volatile RwReg PortReg;
    //  typedef uint32_t PortMask;
    // #else
    //   typedef volatile uint8_t PortReg;
    //   typedef uint8_t PortMask;
    // #endif
    
    #if defined(__AVR__)
    typedef volatile uint8_t PortReg;
    typedef uint8_t PortMask;
    #define HAVE_PORTREG
    #elif defined(__SAM3X8E__)
    typedef volatile RwReg PortReg;
    typedef uint32_t PortMask;
    #define HAVE_PORTREG
    #elif (defined(__arm__) || defined(ARDUINO_FEATHER52)) &&                      \
        !defined(ARDUINO_ARCH_MBED) && !defined(ARDUINO_ARCH_RP2040)
    typedef volatile uint32_t PortReg;
    typedef uint32_t PortMask;
    #define HAVE_PORTREG
    #endif
    
    #include <SPI.h>
    #include <Adafruit_GFX.h>
    
    #define BLACK 0
    #define WHITE 1
    #define INVERSE 2
    
    #define SH1106_I2C_ADDRESS   0x3C // 011110+SA0+RW - 0x3C or 0x3D
    // Address for 128x32 is 0x3C
    // Address for 128x64 is 0x3D (default) or 0x3C (if SA0 is grounded)
    
    /*=========================================================================
        SH1106 Displays
        -----------------------------------------------------------------------
        The driver is used in multiple displays (128x64, 128x32, etc.).
        Select the appropriate display below to create an appropriately
        sized framebuffer, etc.
    
        SH1106_128_64  128x64 pixel display
    
        SH1106_128_32  128x32 pixel display
    
        SH1106_96_16
    
        -----------------------------------------------------------------------*/
       #define SH1106_128_64
    //   #define SH1106_128_32
    //   #define SH1106_96_16
    /*=========================================================================*/
    
    #if defined SH1106_128_64 && defined SH1106_128_32
      #error "Only one SH1106 display can be specified at once in SH1106.h"
    #endif
    #if !defined SH1106_128_64 && !defined SH1106_128_32 && !defined SH1106_96_16
      #error "At least one SH1106 display must be specified in SH1106.h"
    #endif
    
    #if defined SH1106_128_64
      #define SH1106_LCDWIDTH                  128
      #define SH1106_LCDHEIGHT                 64
    #endif
    #if defined SH1106_128_32
      #define SH1106_LCDWIDTH                  128
      #define SH1106_LCDHEIGHT                 32
    #endif
    #if defined SH1106_96_16
      #define SH1106_LCDWIDTH                  96
      #define SH1106_LCDHEIGHT                 16
    #endif
    
    #define SH1106_SETCONTRAST 0x81
    #define SH1106_DISPLAYALLON_RESUME 0xA4
    #define SH1106_DISPLAYALLON 0xA5
    #define SH1106_NORMALDISPLAY 0xA6
    #define SH1106_INVERTDISPLAY 0xA7
    #define SH1106_DISPLAYOFF 0xAE
    #define SH1106_DISPLAYON 0xAF
    
    #define SH1106_SETDISPLAYOFFSET 0xD3
    #define SH1106_SETCOMPINS 0xDA
    
    #define SH1106_SETVCOMDETECT 0xDB
    
    #define SH1106_SETDISPLAYCLOCKDIV 0xD5
    #define SH1106_SETPRECHARGE 0xD9
    
    #define SH1106_SETMULTIPLEX 0xA8
    
    #define SH1106_SETLOWCOLUMN 0x00
    #define SH1106_SETHIGHCOLUMN 0x10
    
    #define SH1106_SETSTARTLINE 0x40
    
    #define SH1106_MEMORYMODE 0x20
    #define SH1106_COLUMNADDR 0x21
    #define SH1106_PAGEADDR   0x22
    
    #define SH1106_COMSCANINC 0xC0
    #define SH1106_COMSCANDEC 0xC8
    
    #define SH1106_SEGREMAP 0xA0
    
    #define SH1106_CHARGEPUMP 0x8D
    
    #define SH1106_EXTERNALVCC 0x1
    #define SH1106_SWITCHCAPVCC 0x2
    
    // Scrolling #defines
    #define SH1106_ACTIVATE_SCROLL 0x2F
    #define SH1106_DEACTIVATE_SCROLL 0x2E
    #define SH1106_SET_VERTICAL_SCROLL_AREA 0xA3
    #define SH1106_RIGHT_HORIZONTAL_SCROLL 0x26
    #define SH1106_LEFT_HORIZONTAL_SCROLL 0x27
    #define SH1106_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29
    #define SH1106_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A
    
    class Adafruit_SH1106 : public Adafruit_GFX {
     public:
      Adafruit_SH1106(int8_t SID, int8_t SCLK, int8_t DC, int8_t RST, int8_t CS);
      Adafruit_SH1106(int8_t DC, int8_t RST, int8_t CS);
      Adafruit_SH1106(int8_t RST);
    
      void begin(uint8_t switchvcc = SH1106_SWITCHCAPVCC, uint8_t i2caddr = SH1106_I2C_ADDRESS, bool reset=true);
      void SH1106_command(uint8_t c);
      void SH1106_data(uint8_t c);
    
      void clearDisplay(void);
      void invertDisplay(uint8_t i);
      void display();
    
      /*void startscrollright(uint8_t start, uint8_t stop);
      void startscrollleft(uint8_t start, uint8_t stop);
    
      void startscrolldiagright(uint8_t start, uint8_t stop);
      void startscrolldiagleft(uint8_t start, uint8_t stop);
      void stopscroll(void); */
      
      void dim(uint8_t contrast);
    
      void drawPixel(int16_t x, int16_t y, uint16_t color);
    
      virtual void drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
      virtual void drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
    
     private:
      int8_t _i2caddr, _vccstate, sid, sclk, dc, rst, cs;
      void fastSPIwrite(uint8_t c);
    
      boolean hwSPI;
      PortReg *mosiport, *clkport, *csport, *dcport;
      PortMask mosipinmask, clkpinmask, cspinmask, dcpinmask;
    
      inline void drawFastVLineInternal(int16_t x, int16_t y, int16_t h, uint16_t color) __attribute__((always_inline));
      inline void drawFastHLineInternal(int16_t x, int16_t y, int16_t w, uint16_t color) __attribute__((always_inline));
    
    };
    And now the example compiles without error! Can't verify though whether it's actually working since I don't have an SH1106 display here.
    Hope you can test this.

    Paul

  5. #5
    Member
    Join Date
    Sep 2019
    Location
    Sevilla, Spain
    Posts
    66
    Quote Originally Posted by PaulS View Post
    Hmm, got the same compilation error when trying to compile the example sh1106_128x64_spi.ino that came with library.

    Since the maker of the library stated on his Github page that his library was a modification of Adafruit's SSD1306 library, I compared the Adafruit_SSD1306.h and Adafruit_SH1106.h files.
    I noticed this difference within the .h files: (it's related to the errors)

    So I modified Adafruit_SH1106.h to look like this:

    And now the example compiles without error! Can't verify though whether it's actually working since I don't have an SH1106 display here.
    Hope you can test this.

    Paul
    Hi Paul,
    It works, and it draws in the whole display with no glitches like the library I was using, and even better, it takes 423 microseconds in the update function instead the 26.000 it was taking with the other library
    you are awesome, thanks a lot for doing this ;-)
    I'm using SPI1 but looks like the library does not support it, so I think it's working as SW SPI,
    Code:
    #define OLED_CLK 0      // CS1
    #define OLED_CS 1       // MISO1
    #define OLED_MOSI 9     //
    #define OLED_DC 26      // MOSI1
    #define OLED_RESET 27   // SCK1

  6. #6
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    9,571
    Quote Originally Posted by M4ngu View Post
    Hi Paul,
    It works, and it draws in the whole display with no glitches like the library I was using, and even better, it takes 423 microseconds in the update function instead the 26.000 it was taking with the other library
    you are awesome, thanks a lot for doing this ;-)
    I'm using SPI1 but looks like the library does not support it, so I think it's working as SW SPI,
    Code:
    #define OLED_CLK 0      // CS1
    #define OLED_CS 1       // MISO1
    #define OLED_MOSI 9     //
    #define OLED_DC 26      // MOSI1
    #define OLED_RESET 27   // SCK1
    You might look at this constructor:
    Code:
    Adafruit_SSD1306::Adafruit_SSD1306(uint8_t w, uint8_t h, SPIClass *spi,
                                       int8_t dc_pin, int8_t rst_pin, int8_t cs_pin,
                                       uint32_t bitrate)
        : Adafruit_GFX(w, h), spi(spi ? spi : &SPI), wire(NULL), buffer(NULL),
          mosiPin(-1), clkPin(-1), dcPin(dc_pin), csPin(cs_pin), rstPin(rst_pin) {
    #ifdef SPI_HAS_TRANSACTION
      spiSettings = SPISettings(bitrate, MSBFIRST, SPI_MODE0);
    #endif
    }
    Which has the opton to pass in SPI1...

  7. #7
    Senior Member PaulS's Avatar
    Join Date
    Apr 2015
    Location
    Netherlands
    Posts
    659
    Quote Originally Posted by M4ngu View Post
    It works, and it draws in the whole display with no glitches like the library I was using
    Great!
    De nada...

    Paul

Posting Permissions

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