SSD1306 doesn't work on ESP32?

Posted on
  • function go(){
    //g.on();
    // write some text
    g.drawString("Hello World!",2,2);
    // write to the screen
    g.flip();
    }

    // SPI
    SPI2.setup({sck:18, mosi:23});
    var g = require("SSD1306").connectSPI(SPI2, 4 /DC/, 12 /RST/, go, { cs:5 });

    no errors, but the OLED doesn't work.

  • I believe the pins 2-6 are used for the flash chip, so best not to use pins 4 & 5.

    Change those to say pins 16,17, rewire and see how you get on.

    var g = require("SSD1306").connectSPI(SPI2, 16 /DC/, 12 /RST/, go, { cs:17 });

    @JumJum - Should we add a warning if these pins are used?

  • In SSD1306.js, connectSPI() has some codes not work well on ESP32, such as digitalPulse(rst,0,10), cs.reset() and cs.set() .

    Just rewrite some lines:

    cs.reset() --> digitalWrite(cs,0)
    cs.set() --> digitalWrite(cs,1)
    digitalPulse(rst,0,10) --> for(var i = 0; i<10; i++){ digitalWrite(rst,0); digitalWrite(rst,1); }
    :-)

    The OLED module works well.

    But, the initial action of SPI and Graphics module must be in the onInit() function. why?
    And the RST pin must be connected! The cs option must be defined too.

    var g;
    
    function start(){
        // write some text
        g.drawString("Hello Espruino!", 2, 2);
        // write to the screen
        g.flip();
    }
    
    function onInit(){
      SPI2.setup({sck:18, mosi:23});
      g = require("mySSD1306").connectSPI(SPI2, 16 /*DC*/, 12 /*RST*/, start, {cs:17});
    }
    
    save();
    
  • mySSD1306.js

    /* Copyright (c) 2014 Sam Sykes, Gordon Williams. See the file LICENSE for copying permission. */
    /*
    Module for the SSD1306 OLED controller in displays like the Crius CO-16
    
    function go(){
     // write some text
     g.drawString("Hello World!",2,2);
     // write to the screen
     g.flip();
    }
    // I2C
    I2C1.setup({scl:B6,sda:B7});
    
    var g = require("SSD1306").connect(I2C1, go);
    // or
    var g = require("SSD1306").connect(I2C1, go, { address: 0x3C });
    
    // SPI
    var s = new SPI();
    s.setup({mosi: B6, sck:B5});
    var g = require("SSD1306").connectSPI(s, A8, B7, go);
    
    */
    var C = {
     OLED_WIDTH                 : 128,
     OLED_CHAR                  : 0x40,
     OLED_CHUNK                 : 128
    };
    
    // commands sent when initialising the display
    var extVcc=false; // if true, don't start charge pump
    var initCmds = new Uint8Array([
                 0xAe, // 0 disp off
                 0xD5, // 1 clk div
                 0x80, // 2 suggested ratio
                 0xA8, 63, // 3 set multiplex, height-1
                 0xD3,0x0, // 5 display offset
                 0x40, // 7 start line
                 0x8D, extVcc?0x10:0x14, // 8 charge pump
                 0x20,0x0, // 10 memory mode
                 0xA1, // 12 seg remap 1
                 0xC8, // 13 comscandec
                 0xDA, 0x12, // 14 set compins, height==64 ? 0x12:0x02,
                 0x81, extVcc?0x9F:0xCF, // 16 set contrast
                 0xD9, extVcc?0x22:0xF1, // 18 set precharge
                 0xDb, 0x40, // 20 set vcom detect
                 0xA4, // 22 display all on
                 0xA6, // 23 display normal (non-inverted)
                 0xAf // 24 disp on
                ]);
    // commands sent when sending data to the display
    var flipCmds = [
         0x21, // columns
         0, C.OLED_WIDTH-1,
         0x22, // pages
         0, 7 /* (height>>3)-1 */];
    function update(options) {
      if (options) {
        if (options.height) {
          initCmds[4] = options.height-1;
          initCmds[15] = options.height==64 ? 0x12 : 0x02;
          flipCmds[5] = (options.height>>3)-1;
        }
        if (options.contrast!==undefined) initCmds[17] = options.contrast;
      }
    }
    
    
    exports.connect = function(i2c, callback, options) {
      update(options);
      var oled = Graphics.createArrayBuffer(C.OLED_WIDTH,­initCmds[4]+1,1,{vertical_byte : true});
    
      var addr = 0x3C;
      if(options) {
        if (options.address) addr = options.address;
        // reset display if 'rst' is part of options
        if (options.rst) digitalPulse(options.rst, 0, 10);
      }
    
      setTimeout(function() {
        // configure the OLED
        initCmds.forEach(function(d) {i2c.writeTo(addr, [0,d]);});;
      }, 50);
    
      // if there is a callback, call it now(ish)
      if (callback !== undefined) setTimeout(callback, 100);
    
      // write to the screen
      oled.flip = function() {
        // set how the data is to be sent (whole screen)
        flipCmds.forEach(function(d) {i2c.writeTo(addr, [0,d]);});;
        var chunk = new Uint8Array(C.OLED_CHUNK+1);
    
        chunk[0] = C.OLED_CHAR;
        for (var p=0; p<this.buffer.length; p+=C.OLED_CHUNK) {
          chunk.set(new Uint8Array(this.buffer,p,C.OLED_CHUNK), 1);
          i2c.writeTo(addr, chunk);
        }
      };
    
      // set contrast, 0..255
      oled.setContrast = function(c) { i2c.writeTo(addr, 0, 0x81, c); };
    
      // set off
      oled.off = function() { i2c.writeTo(addr, 0, 0xAE); }
    
      // set on
      oled.on = function() { i2c.writeTo(addr, 0, 0xAF); }
    
      // return graphics
      return oled;
    };
    
    exports.connectSPI = function(spi, dc,  rst, callback, options) {
      update(options);
      var cs = options?options.cs:undefined;
      var oled = Graphics.createArrayBuffer(C.OLED_WIDTH,­initCmds[4]+1,1,{vertical_byte : true});
    
    
      if (rst) {
        //digitalPulse(rst,0,10);
        for(var i = 0; i<10; i++){
          digitalWrite(rst,0);
          digitalWrite(rst,1);
        }
      }
    
      setTimeout(function() {
        if (cs) digitalWrite(cs,0);
        // configure the OLED
        digitalWrite(dc,0); // command
        spi.write(initCmds);
        digitalWrite(dc,1); // data
        if (cs) digitalWrite(cs,10);
        // if there is a callback, call it now(ish)
        if (callback !== undefined) setTimeout(callback, 10);
      }, 50);
    
      // write to the screen
      oled.flip = function() {
        // set how the data is to be sent (whole screen)
        if (cs) digitalWrite(cs,0);
        digitalWrite(dc,0);// command
        spi.write(flipCmds);
        digitalWrite(dc,1);// data
        spi.write(this.buffer);
        if (cs) digitalWrite(cs,1);
      };
    
      // set contrast, 0..255
      oled.setContrast = function(c) {
        if (cs) digitalWrite(cs,0);//cs.reset();
        spi.write(0x81,c,dc);
        if (cs) digitalWrite(cs,1);//cs.set();
      };
    
      // set off
      oled.off = function() {
        if (cs) digitalWrite(cs,0);//cs.reset();
        spi.write(0xAE,dc);
        if (cs) digitalWrite(cs,1);//cs.set();
      };
    
      // set on
      oled.on = function() {
        if (cs) digitalWrite(cs,0);//cs.reset();
        spi.write(0xAF,dc);
        if (cs) digitalWrite(cs,1);//cs.set();
      };
    
      // return graphics
      return oled;
    };
    
    
  • But, the initial action of SPI and Graphics module must be in the onInit() function. why?
    And the RST pin must be connected! The cs option must be defined too.

    because connectSPI send some init commands to make the OLED work correct.

    ....  
    setTimeout(function() {
        // configure the OLED
        initCmds.forEach(function(d) {i2c.writeTo(addr, [0,d]);});;
      }, 50);
    ....
    
  • @user73896
    We are still in the process of debugging the ESP32 code.

    Please can you confirm the following

    a. I'm surprised this did not work:
    cs.reset() and cs.set()

    Please can you re-test?

    b. digitalPulse(rst,0,10)

    I'm not sure if this has been implemented - @JumJum - can you recall?

  • comfirmed that D21.reset() does not turn off.
    Raised:
    https://github.com/espruino/Espruino/iss­ues/1103

  • in mySSD1360.js, in exports.connectSPI function ,

    if (rst) {
        digitalPulse(rst,0,10);
        /*
        for(var i = 0; i<10; i++){
          digitalWrite(rst,0);
          digitalWrite(rst,1);
        }
        */
      }
    

    the OLED dosn't work.

    then , try

    if (rst) {
        //digitalPulse(rst,0,10);
        for(var i = 0; i<10; i++){
          digitalWrite(rst,0);
          digitalWrite(rst,1);
        }
      }
    

    the OLDE works well.

    so, I think digitalPulse(rst,0,10) doesn't works correctly.

  • I' sorry, pin.set() and reset() can work well, D21.set and reset works on my widora v5.0 ESP32 board.

  • digitalPulse(rst,0,10) sends one pulse to gnd for 10 msecs
    Is this what you need, or do you need 10 pulses ?

  • @jumjum
    I thînk the line came from an existing module.

    I think it is meant to set to low for 10 ms then finish in the high state. That's how I read that reference documentation.

  • If there is a pulse only, replacing this by 10 times on/off is a bit strange.

  • eg. digitalPulse(A0,1,5); pulses A0 high for 5ms. digitalPulse(A0,1,[5,2,4]); pulses A0 high for 5ms, low for 2ms, and high for 4ms.

    It seems that digitalPulse(rst,0,10) sets rst pin( rst = 1) , and then resets it for 10ms(rst = 0), at last sets it again(rst = 1).

    Yet, it doesn't work.

  • Hi @Aifer,

    check the state of your rest pin, should be "input_pullup" to make digitalPulse(rst,0,10) work

  • Hi, @MaBe
    In SSD1306.js / connectSPI() function

    1)

    if (rst) {
        pinMode(rst, "input_pullup");
        digitalPulse(rst,0,10);
      }
    

    Not work.

    2)

    if (rst) {
        pinMode(rst, "input_pullup");
        digitalPulse(rst,1,10);
      }
    

    Work well.

    3)

    if (rst) {
        //pinMode(rst, "input_pullup");
        digitalPulse(rst,1,10);
      }
    

    Work well.

    4)

    if (rst) {
        digitalWrite(rst,1);
        digitalWrite(rst,0);
        setTimeout(function(){ digitalWrite(rst,1); },10);
      }
    

    Work well.

    5)

    if (rst) {
        digitalWrite(rst,0);
        digitalWrite(rst,1);
        setTimeout(function(){ digitalWrite(rst,0); },10);
      }
    

    Not work.

    6)

    if (rst) {
        pinMode(rst, "input_pullup");
        digitalWrite(rst,1);
        digitalWrite(rst,0);
        setTimeout(function(){ digitalWrite(rst,1); },10);
      }
    

    Work well.

    7)

    if (rst) {
        pinMode(rst, "input_pullup");
        digitalWrite(rst,0);
        digitalWrite(rst,1);
        setTimeout(function(){ digitalWrite(rst,0); },10);
      }
    

    Work well.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

SSD1306 doesn't work on ESP32?

Posted by Avatar for Aifer @Aifer

Actions