I2C timeout with OLED display on Pico

Posted on
Page
of 2
/ 2
Next
  • Hi folks,

    I spent hours trying to print something on some OLED displays I received from HobbyKing (http://www.hobbyking.com/hobbyking/store­/__55110__Multiwii_OLED_Display_Module_I­2C_128x64_Dot_MWC_AU_Warehouse_.html).
    I guess the silicon is SSD1306.
    However, Espruino tells me "Timeout on I2C Write Transmit Mode 2" everytime, in every configuration. I tried to downgrade Espruino, I tried putting some Pull-up on 3V3, I tried powering the module on 3V3 or on VBAT, I tried I2C1 and I2C2, I tried to decrease the clock down to 1kHz,I tried to modify the SSD1306 module in order to change its I2C address (browsed whole range from 0x00 to 0x7F), I tried to shake my display, I tried almost everything.... "I2C timeout" tells my Pico......

    If someone used to play with those Multiwii OLED displays, I will be grateful to learn from your experience.

    My current config is:

    "I2C timeout" . . . aaaAARARRGHHHHHH !!!!!

  • I2C timeout basically means at the lowest level, the Pico can't get a response off the display at the given address. So it's almost certainly some wiring issue (or a broken display)

    Are you connecting to Bat or Vcc when you're trying to get 5v? Bat won't have anything on it (it's the battery input) but Vcc (the one next to 3.3v) will have around 4.5v (5v plus diode drop).

    Are you using the 0.1" pins, or the small connector? It looks like the 0.1" pins might not be connected to the same things as the small connector (so might not have I2C on them).

    Also, are you sure SDA and SCL aren't mixed up? I always end up doing that :)

  • Do you have a pullup resistor between Vcc and SDA, Vcc and SCL?

    I have actually also never had any luck making those displays work, though I've only tried two, and both are suspect. One I'm not sure I got into I2C mode (it had pins like a centipede for a million interfaces), and the other one doesn't have the voltage regulator, and I accidentally applied 5v to it instead of 3.3 (mine was spec'ed 2.6-3.3), so it may be dead.

  • @Gordon: I tried to power the display through the VBAT and 3V3 (right next to the GND pin).
    I am using the connector on the display side. I tried to swap SCL and SDA too. I got 3 displays out of the box, I tried each display, same behaviour.

    @DrAzzy: I have 10k pull-ups on both SDA and SCL. I although tried to put 4k7 resistors, without any better results. The display is rated between 3V3 and 5V. In my case, I could not damage it (or should I say , damage them, because I tried each of my 3 displays)

    Weird, isn't it?

  • Yes, it's really strange. Just looked at the datasheet: http://www.embeddedadventures.com/datash­eets/SSD1306-Revision%201.1%20(Charge%20­Pump).pdf

    See 8.1 MCU Interface selection. It may well be that your OLED is in 3 wire SPI mode, not I2C. It might correlate with what one of the comments on the hobbyking page said:

    OK. After some experimenting, this display works actually fine with some caveats ! Multiwii uses its own i2c libraries and this display will work with these. However this board doesn't connect SDAin and SDAout and hence will not work with standard Arduino libraries using the wire library ... Luckily, there is an easy fix ! Just put a solder bridge between pins 19 and 20 of the flat cable going to the OLED and everything works :-) The i2c address is 0x3C and google for "GOFi2cOLED" and you will find a very good Arduino library that works 100% with this display :-) I'll post a picture under the files section of the hack to solder pins 19 and 20. Might be good that HobbyKing upgrades the board with these pins properly connected ... Good luck.

    I actually have a board that's like that - this one: http://www.embeddedadventures.com/oled_d­isplay_128x64_OLED-12864-WHITE.html

    So I'll see if I can come up with a 3 wire SPI version - just shorting those pins might be easier though!

  • @Gordon: Gordon, you got the answer! "Luckily, there is an easy fix ! Just put a solder bridge between pins 19 and 20 of the flat cable going to the OLED and everything works :-)"
    I soldered pin 19&20 together, and, TadaAAAAaM, it just works!
    I spent hours reading threads and comments, I did not cross that one!

    Thank you Gordon!

    Just a bit of further information: For those who bought their OLED displays on Hobbyking (the ones that are manufactured by hexTronik). You should not have to patch the reset circuit, it already exists on the PCB (R3 and C10, next to pin 14). If someone wants to have a look at the patch, you'll find nice pictures of the patch here: https://github.com/hallard/ArduiPi_SSD13­06/issues/1


    1 Attachment

    • 2015-04-24 20.33.07.jpg
  • Good find, I'll look into that on mine...

    I've got an SPI and I2C version (the latter being possibly fried) sitting on my desk.

  • Hmm, I2C version now doesn't complain (now that I've shorted pins 19 and 20, but it also doesn't work - screen remains dark.

    Mine is a Heltek (hell-tech?)

  • Could be it needs 5v? It seems like the power supply for the OLEDs is pretty flaky on some of them.

    The fact that it responds to I2C is good though - at least the driver chip is active.

  • DrAzzy, I have a Heltec 128x64 I2C screen that I have been using with Arduino. It took me some time to get it to work, because it didn't send and ACK back that most drivers expected. Could this be a problem here? I haven't tested it with my Espruino Pico yet...

  • I have the Heltec, too. Could never get them to work (changed 3V3 and 5V, with or without pullups).

  • Did you both try shorting pins 19-20 together? That's most likely the problem with these boards.

    Potentially we could come up with a non-I2C driver that would still work on those screens I guess... it shouldn't be too difficult.

  • Now I have tried my Heltecs and I cant get them to work. Shorted pins 19-20 on one of them, and Im using 4k7 pull up resistors on SCL and SDA. Tried both 3.3V and 5V. I get "Uncaught InternalError: Timeout on I2C Write BUSY".

    The screens works great with an Arduino.

  • Hmmm, I don't get errors now that I've shorted 19 and 20, just blank screen

  • I also have an SPI-based board (Adafruit). So is there an SPI version of the SSD1306 library? I'm not sure whether it would be a good idea to modify a board that doesn't even have the I2C pins...

  • No SPI version - I suspect it would be a very easy conversion, though - practically find/replace.

  • @Dennis, do you have a link to the display? Is it this one? If so, Adafruit have actually provided solder jumpers specifically so you can choose if you want I2C.

    As @DrAzzy says, it shouldn't be too hard to change the driver, but then you have to choose which version of SPI you want. Some use 9 bit SPI, and some use a separate wire for Data/Command :(

  • I have this one:
    http://www.adafruit.com/products/938

    and I also have some of these that I got cheap somewhere:
    http://www.sainsmart.com/sainsmart-0-96-­spi-serial-128x64-oled-for-raspberry-pi-­arduino-mega2560-uno-r3-arm.html

    Indeed the Adafruit board can be modified, but I don't see how this could be done with the SainSmart one. It seems like it would be very handy to have an SPI version of the library (or even a unified one that can be used with either SPI or I2C)

  • You could try this:

    var exports = {};
    
    var C = {
     OLED_CMD                   : 0x80,
     OLED_WIDTH                 : 128,
     OLED_HEIGHT                : 64
    };
    
    // export
    exports.connect = function(spi, dc, callback) {
     var oled = Graphics.createArrayBuffer(128,64,1,{ver­tical_byte : true});
     var w = function(c,d) {
       digitalWrite(dc,0);
       spi.write(c);
       digitalWrite(dc,1);
       spi.write(c);
     };
     var extVcc=false;
     
     // configure the OLED
     digitalWrite(dc,0);// command
     spi.write([ 0xAe, // disp off
                 0xD5, // clk div
                 0x80, // suggested ratio
                 0xA8, C.OLED_HEIGHT-1, // set multiplex
                 0xD3,0x0, // display offset
                 0x40, // start line
                 0x8D,extVcc?0x10:0x14, // charge pump
                 0x20,0x0, // memory mode
                 0xA1, // seg remap 1
                 0xC8, // comscandec
                 0xDA,0x12, // set compins
                 0x81,extVcc?0x9F:0xCF, // set contrast
                 0xD9,extVcc?0x22:0xF1, // set precharge
                 0xDb,0x40, // set vcom detect
                 0xA4, // display all on
                 0xA6, // display normal (non-inverted)
                 0xAf // disp on
                ]);
       digitalWrite(dc,1);// data
     
     // if there is a callback, call it now(ish)
     if (callback !== undefined) setTimeout(callback, 10);
      
     // write to the screen
     oled.flip = function() { 
       // set how the data is to be sent (whole screen)
       digitalWrite(dc,0);// command
       spi.write([0x21, // columns
         0, C.OLED_WIDTH-1,
         0x22, // rows
         0, 7]);
       digitalWrite(dc,1);// data
       spi.write(this.buffer);
      };
     
     // return graphics
     return oled;
    };
    
    
    
    B3.reset(); // GND
    B4.set(); // VCC
    
    digitalPulse(B7,0,10); // Reset
    
    setTimeout(function() {
      var s = new SPI();
      s.setup({mosi: B6 /* D1 */, sck:B5 /* D0 */});
      var g = exports.connect(s, A8 /* DC */, function(){
       // write some text
       g.drawString("Hello World!",2,2);
       // write to the screen
       g.flip(); 
      }
     );
    },50);
    

    Just gave it a go and it seems to work. I'll have a go at tidying it up into a general purpose I2C+SPI module - I shamelessly copied the magic initialisation incantation from Adafruit and it seems to work - looks like some oleds needed more setup than I was giving them

  • Just to add - looks like some displays have a proper power supply on them, and some use a charge pump.

    The previous code handled displays with a proper power supply, and it didn't set up the charge pump. It's why some displays might not have worked.

  • Ok, updated now, so no need for the code above - see http://www.espruino.com/SSD1306

  • Awesome! I got it to work with the Adafruit display and SPI!
    Unfortunately the SainSmart display only shows pixel garbage :(

  • Unfortunately the SainSmart display only shows pixel garbage :(

    Well, that's a start. It means that the initialisation code is more or less working... And that's connected via SPI?

    I wonder whether there's some difference in what needs sending to it - if you can find some example code that works with it then we could compare.

  • Hello, just hijacking this thread. I have been tinkering with a (non Adafruit) OLED and get the same result as @Dennis in that it connects but just shows a load of junk on the screen.

    I have removed the contents of the callback so that I only connect to the screen and don't send any data to it other than what's in the initCmds array and still get the garbage, so I guess it's to do with the init voodoo.

    Weirdly the Adafruit library works with the screen on Arduino (apart from I have to change the address). I have looked at the datasheets but I have to confess they are a complete mystery to me and wouldn't really know where to start in changing the init variables.

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

I2C timeout with OLED display on Pico

Posted by Avatar for Jean-Philippe_Rey @Jean-Philippe_Rey

Actions