Keyes OLED Display not Working.

I just received my Keyes brand 0.96" 128x64 OLED and thought I was buying quality.

Pretty soon after powering up, display section separated from the PCB. Probably the glue is heated up and lost its "stick".

Any way I tried the examples in the Uglib and the Adafruit libraries and so far only get 2 tone snow. Yellow at top, blue below.

The online product info is incorrect. The unit is I2C and not SPI. The pictures are the same as my module.

The address in the pic shows 0x78.

Has anyone got one of these unit to run, and if so - how/where did u specify the address?

Well, then please post a picture of your setup and some more information: Which Arduino board, which u8glib constructor...

Oliver

olikraus: Well, then please post a picture of your setup and some more information: Which Arduino board, which u8glib constructor...

Oliver

Setup was a basic test setup with an Uno and the Oled connected with Dupont cables as follows:

Uno Oled


3V3 VCC GND GND A4 SDA A5 SCL

Sketch was the Hello World example. I tested with EACH of the constructors in the below sketch in turn:

/*

  HelloWorld.pde
  
  "Hello World!" example code.
  
  >>> Before compiling: Please remove comment from the constructor of the 
  >>> connected graphics display (see below).
  
  Universal 8bit Graphics Library, https://github.com/olikraus/u8glib/
  
  Copyright (c) 2012, olikraus@gmail.com
  All rights reserved.

  Redistribution and use in source and binary forms, with or without modification, 
  are permitted provided that the following conditions are met:

  * Redistributions of source code must retain the above copyright notice, this list 
    of conditions and the following disclaimer.
    
  * Redistributions in binary form must reproduce the above copyright notice, this 
    list of conditions and the following disclaimer in the documentation and/or other 
    materials provided with the distribution.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
  CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 
  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
  
*/


#include "U8glib.h"

// setup u8g object, please remove comment from one of the following constructor calls
//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0);    // I2C / TWI 
//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_NO_ACK|U8G_I2C_OPT_FAST); // Fast I2C / TWI 
//U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NO_ACK);    // Display which does not send AC
U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE); // I2C / TWI 
//U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_DEV_0|U8G_I2C_OPT_FAST); // Dev 0, Fast I2C / TWI
//U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NO_ACK); // Display which does not send ACK


void draw(void) {
  // graphic commands to redraw the complete screen should be placed here  
  u8g.setFont(u8g_font_unifont);
  //u8g.setFont(u8g_font_osb21);
  u8g.drawStr( 0, 22, "Hello World!");
}

void setup(void) {
  // flip screen, if required
  // u8g.setRot180();
  
  // set SPI backup if required
  //u8g.setHardwareBackup(u8g_backup_avr_spi);

  // assign default color value
  if ( u8g.getMode() == U8G_MODE_R3G3B2 ) {
    u8g.setColorIndex(255);     // white
  }
  else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
    u8g.setColorIndex(3);         // max intensity
  }
  else if ( u8g.getMode() == U8G_MODE_BW ) {
    u8g.setColorIndex(1);         // pixel on
  }
  else if ( u8g.getMode() == U8G_MODE_HICOLOR ) {
    u8g.setHiColorByRGB(255,255,255);
  }
}

void loop(void) {
  // picture loop
  u8g.firstPage();  
  do {
    draw();
  } while( u8g.nextPage() );
  
  // rebuild the picture after some delay
  delay(50);
}

All the constructors gave the same result - 2-tone snow. FWIW the display is a Yellow/Blue colour display.

Where do I change the address setting?

Did you try the 5V supply also? Will this make a difference?

Oliver

Yes, tried 5V as well - no joy.

Can we try to change the address? - it is the only thing I can think of.

Hi

You can change the I2C address in line 60 of the file u8g_com_arduino_ssd_i2c.c.

Oliver

I still don't have this working which is a bit frustrating.

The default address in the library is "0x3c*2". On the back of the unit there are 2 addresses viz "0x7A" and "0x78". There appears to be 0 ohm resistor selecting 0x78. I ran i2c scanner and it reports an address of "3c" in row 3 col c. Maybe that's why it's 0x3c*2.

I think I read somewhere 0x3c*2 is the same as 0x78 - but not sure.

Anyway I changed the address to "0x3c", but still no joy and reset has no effect. With 0x78 the screen does cycle on reset.

Is there anything else I can check? Is there any sure-fired way to check if the unit is a dud?

BTW how can I tell if its an SH1106 or an SSD1306?

0x03c*2 is equal to 0x078. In I2C it is not so clear whether it is the address goes from 0 to 127 or from 0 to 254 (only using the even numbers).

With 0x78 the screen does cycle on reset. What does this mean? Can you post a picture? How is your setup for this? Picture?

BTW how can I tell if its an SH1106 or an SSD1306? The seller must tell you. But both constructors will at least show something.

Oliver

olikraus: 0x03c*2 is equal to 0x078

hmmm so 0x078 and not 0x78.

With 0x78 the screen does cycle on reset. What does this mean? Can you post a picture? How is your setup for this? Picture?

I am using a bare Uno with only the OLED connected to 5v/GND and i2C i.e. A4 and A5. It means when I press the reset button on the Uno, the screen goes blank, then displays snow again.

BTW how can I tell if its an SH1106 or an SSD1306? The seller must tell you. But both constructors will at least show something.

Not gonna happen. They have the wrong info on their web site. I contacted them and asked for the info. They gave me the same incorrect info as on the web site - AND they are the manufacturer!!! Yes, with both constructors I get 2-colour snow.

I got one of these Yellow/Blue Keyes OLEDs the other day and had exactly the same snow display.

Googled around for any information and it turns out that there’s a problem with the design of the display - there’s no reset. Although it doesn’t have a reset connection, unlike other makes (such as Heltec) it won’t even allow a reset. Pin 14 (on the display ribbon connection) is permanently connected to VCC. However, in order to create a reset, pin 14 needs to temporarily be connected to GND, which is impossible the way that the board is set up.

Other 4-pin OLEDs get around this by creating a reset pulse when the OLED is switched on. The usual method is by connecting pin 14 to VCC (or a 3v3 supply from an on-board regulator) via a 10k resistor and also connecting pin 14 to GND via a 100n cap. This is the arrangement that Heltec uses.

There are a few ways mentioned about what can be done to cure the problem, but none of the non-invasive ones, such as using a LED or 100R resistor in series with VCC worked for me. Other options included what seemed to be a bit of messing about, such as temporarily shorting pin 14/R3 to GND which I didn’t try as I wanted a permanent solution. Another option (if I remember correctly) involves soldering a wire onto R4/pin 14 and connecting that to the Arduino as a reset wire and adding code into the Arduino program. As that would effectively short out VCC to GND, I wasn’t going to bother to try that either.

As I saw it, the solution was simply to add the pulse circuit to pin 14 and then the Keyes OLED would work like the Haltec one. I finally got round to doing it this afternoon. It’s an easy enough job, but it does involve some fine soldering work (not much) and good eyesight :slight_smile:

Brief circuit description
Ribbon cable pin 14 connects to R4 which connects to VCC. R4 is in fact just a link (these are sometimes labelled as 0 or 0R and are often known as 0R resistors). This means that pin 14 is going directly to VCC through R4.

Doing it
The simplest solution is to replace R4 with a 10k resistor. R4 is surface mounted (SMD) and is a size 0805. Luckily I had some 10k 0805 SMDs and I just removed the existing R4 (I found it easier to gently snap the resistor in 2 with a pair of side cutters and then unsolder each end) and replaced it with the 10k. That was half the job done!. The second half was fitting the capacitor. One end of the capacitor needed to be soldered to the pin 14 side of R4 and the other end to GND.

There were two handy GND points I could use - pins 15 and 16 both connect to GND and so I could have soldered one end of the capacitor to there. If I had a 1206 size 100nF capacitor I might have been tempted, but as I didn’t and was using a capacitor with legs on, I decided to connect it to the far end of either R1, C3 or C4. This also has the advantage that it avoided any risk of occidentally creating solder bridges across other terminals on the ribbon cable.

I used a 100nF ceramic disc capacitor. I trimmed one leg very short and soldered this to the far end of C4. I trimmed a bit off the other leg, slid on a piece of sleeving (to prevent the bare leg shorting against any other component) and soldered the leg to the far end of R4. I checked the work to make sure there were no shorts anywhere, then connected the OLED up to the Arduino. Snow! However, after a few seconds the snow disappeared and was replaced by Hello World. Success!. I think the initial few seconds delay was due to the pulse kicking in. Subsequent turning on and off brought the normal display up instantly. Therefore, it seems that it only needs to be reset occasionally, even though it will be reset every time it is switched on.

The connections to the Arduino were the standard ones - 5 for SDL, 4 for SDA plus 5v and GND.
Library used - U8glib
constructor call:
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0); // I2C / TWI

The OLED address remained the default 0x78. I’ve left the OLED running for the past six hours and all is OK. It also seems to work OK on 3v3 from the Arduino, so I might use that when I can.

I’ve attached some before and after photos of the OLED showing the alterations. It’s not as tidy as I’d like it, but at least it works :slight_smile:

Edit
I’ve noticed that, because of the sleeving on the capacitor lead, the photo doesn’t show clearly where it connects to on R4. See the newly added CapConnections photo for clarification.

PS - more information on this problem here (also see the links on that page):

KeywsSnow.jpg

Hi Rogmi, finally some good news even if it is to advise the unit is faulty :) Thanks for sharing your fix and the link to the alternative fixes. It of course good to know the problem and the fix.

I don't have any SMD resistors so probably won't be doing the same fix as you. I will investigate some of the alternative fixes and post back the results.

Thanks again - really appreciate you taking the time to make such a detailed post.

I don't know how the design got passed, let alone developed into a product that was then put out for sale. According to the Keyes website, it is still current and the picture they show still looks the same: http://en.keyes-robot.com/productshow.aspx?id=512

Even under the products tab, they give details for a six pin device (which includes the RST and D/C pins) and so they can't even get that right!

Just for my own reference, I might draw and post the circuit diagram for the board later on, there's very little on it and I already have it in rough.

Because I've now made the change, I can't experiment with it. I already have another board on order and perhaps I'll try out a couple of things to see how the reset works before I make the permanent RC modification..

I'm not sure when the OLED would need to be reset. I assume the first time that it's used, as it will initially have random junk (the snow). Once reset, I assume that it can be used by the sketch, but I don't know how long it will stay like that and / or it will need resetting with every new sketch or change to the display - i.e.., permanently showing Hello World might be OK, but what about when used as a clock or thermometer with continually changing display?. On a post somewhere, there was mention that the OLED went to snow / interference every few hours and needed resetting again. I can't remember if it was the Keyes module or a different make, but it wasn't one that had had the resistor / capacitor mod done to it.

From a display point of view, I'm quite happy with it so far. I don't know if it is the same manufacturer that makes all the OLED displays (the bit on the end of the ribbon cable) and differnet manufacturers design their own boards (in which case the display itself should always perform the same), or if there are also different makes of displays as well.

The price of the OLED displays have suddenly rocketed on ebay over the past three weeks. Originally, the 0.96" Heltec displays I bought were selling for £2.85 from China. They then went straight up to around £4.40. The same rise percent occurred with various other sellers. I'd have preferred another Heltec, but as they'd gone up, I bid at different auctions for the Keyes one. This is currently on sale for about £3.40.

I just got an oled and only get this with adafruit sample program on address 3c. |500x500

screen is completely blank using u8glib samples (I adjusted the address to 0x3c*2).

before I try the reset circuit fix, is there no reset command that can be sent to ssd1306?

thanks.

I haven't tried a fix yet. Look on the back of the module, the address ix 0x78. I get the same snow with U8glib and address 0x78.

Follow the link at the bottom of post #9. It will bring up another post with a link. Follow that link - seems there are a variety of fixes, depending on the actual problem.

yes I have read them. I'll try the resistor to vcc later today to see if that works.

mine is a keyes oled and the "resistor" connected to pin 14 is unmarked, so I supposed that is the 0 ohm resistor.

I have a 10k 0805 resistor, and will try to find a capacitor from a junk board to try. I think 0.1uf (same as 100nf) comes in 0402 size so that might fit on the pads for pins 14 and 15/16.

I think the datasheet for ssd1306 says 1us minimum is required for reset. so the 10k*0.1uf=1ms RC gives enough time for reset pin voltage to be in low state.

Hi All

As i tried to explain 0x078 is identical 0x03c*2. It also does not matter whether there is another "0" after the 0x, so 0x078 and 0x78 are identical.

All OLEDs i know, are shipped with 0x78 / 0x3c, so the default settings u8glib should be fine.

Additionally remark: I have some I2C OLEDs, but all of them worked without additional reset circuit (although all of them from other sellers)

Oliver

doughboy: I just got an oled and only get this with adafruit sample program on address 3c.

screen is completely blank using u8glib samples (I adjusted the address to 0x3c*2).

before I try the reset circuit fix, is there no reset command that can be sent to ssd1306?

thanks.

The problem is that, as far as I can see, the only way to reset with a reset command is to have a separate reset wire from the Arduino to the OLED. This then needs to temporarily ground pin 14 to allow the reset to occur. As pin 14 is directly connected to VCC via link R4, then this can't be done VCC would have to effectively be shorted to GND for pin 14 to go to GND. If the reset was sent from the Arduino, the Arduino would have to sink a lot of current and I'm certain that the current sink on a pin is limited to act as damage protection.

The other option, is to very briefly manually short VCC to GND and hope that the temporary drop in voltage might be enough to reset the OLED. This was suggested by somebody and I can't remember if anybody said it worked or not.

I received a different OLED today - a 6 pin SPI version. Doesn't work yet, but I'm still playing around with it and I need to experiment with the arduino pins.

This OLED does have a reset (RST) pin and is reset by a command from the arduino. Looking at the circuit, OLED pin 14 is connected to VCC via a 10k resistor (as is used in the modification). The resistor allows full VCC to go to pin 14, but will limit the current (and thus drop the voltage) if pin 14 is shorted to GND.

On the modification, connecting the 100n capacitor between pin 14 and GND, effectively shorts pin 14 to GND as the capacitor will conduct when discharged. The resistor limits the current and so pin 14 will also be at GND for the brief spell that the capacitor charges up when the OLED is switched on. When the capacitor is charged, it stops conducting and pin 14 will return to full VCC. This initial pulse (or delay) is what resets the OLED.

When the arduino is used to send a reset pulse, as in the case of the SPI that has no capacitor, pin 14 will effectively be shorted to ground via the reset wire as the arduino pin turns to 0v for the duration of the pulse. The only difference between using a capacitor and a reset pulse from the arduino is that the capacitor creates a fixed duration pulse, whereas the pulse from the arduino can be as long or short as required by simply altering the amount of time that the arduino pin is at GND.

Sorry for the long explanation :-), but that's why the arduino can't be used to send a reset pulse without modifying the OLED - there's nowhere to connect the reset wire to for a guaranteed reset. It has been suggested elsewhere in one of the options that the reset wire can be connected between the arduino and pin 14 and indeed it has apparently worked sometimes. However, it may depend on the type of OLED board used and whether pin14 is directly connected to VCC or not. Where pin 14 is directly connected to VCC, as in the Keyes board, I don't think that's likely to work.

olikraus: Hi All

As i tried to explain 0x078 is identical 0x03c*2. It also does not matter whether there is another "0" after the 0x, so 0x078 and 0x78 are identical.

All OLEDs i know, are shipped with 0x78 / 0x3c, so the default settings u8glib should be fine.

Additionally remark: I have some I2C OLEDs, but all of them worked without additional reset circuit (although all of them from other sellers)

Oliver

So I don't have to change line 60 of u8g_com_arduino_ssd_i2c.c from

#define I2C_SLA         (0x3D*2)

to this?

#define I2C_SLA         (0x3C*2)

I'm using the download from bintray. maybe that is not the latest version? I tried downloading the source from github but I think that is not meant to be used as arduino library as is.

It could be the oleds you tried with no reset pin already has reset circuit built in. Like the CRIUS board v1.2 has it built in.

Rogmi: The problem is that, as far as I can see, the only way to reset with a reset command is to have a separate reset wire from the Arduino to the OLED. This then needs to temporarily ground pin 14 to allow the reset to occur. As pin 14 is directly connected to VCC via link R4, then this can't be done VCC would have to effectively be shorted to GND for pin 14 to go to GND. If the reset was sent from the Arduino, the Arduino would have to sink a lot of current and I'm certain that the current sink on a pin is limited to act as damage protection.

by reset command, I meant sending a "reset" command to ssd1306 command register. I checked the datasheet and there is no support for soft reset.

sorry I did not explicitly say soft reset. Your explanation all pertains to hard reset.

doughboy: yes I have read them. I'll try the resistor to vcc later today to see if that works.

mine is a keyes oled and the "resistor" connected to pin 14 is unmarked, so I supposed that is the 0 ohm resistor.

I have a 10k 0805 resistor, and will try to find a capacitor from a junk board to try. I think 0.1uf (same as 100nf) comes in 0402 size so that might fit on the pads for pins 14 and 15/16.

I think the datasheet for ssd1306 says 1us minimum is required for reset. so the 10k*0.1uf=1ms RC gives enough time for reset pin voltage to be in low state.

0402? I struggled with 0805! I've done little SMD work to date, other than a few of resoldering jobs where I've knocked off the capacitors on LED strips or messed about with an SMD practice board. 1206 is just about right for me. Mind you, I had one of those arduino OLED watch kits with the silicon strap arrive today that I got from an ebay auction. All SMD work, including the arduino chip and will have to solder the OLED ribbon onto the PCB. It could be interesting, but the watch isn't all it's made out to be..