128x32 SPI SSD1306 compatible Display only works if GND is removed

Hello,

I have got a strange issue, hope someone can help me.

Short description:

After “Reset” of the Arduino dispaly stops working until I remove GND, reset the Arduino and after one sec I plug in GND back to the GND PIN.

First some Data:
Display:
http://m.ebay.com/itm/SPI-0-91-quot-128x32-White-OLED-LCD-Display-Module-AVR-PIC-for-Arduino-DC-3-3-5V-/201493774341?txnId=1334271167010

and a Arduino Nano.

The Library sample and my modified Test are working:

My modified Hardware SPI Test Code:

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>


/* 
// If using software SPI (the default case):
#define OLED_MOSI   9
#define OLED_CLK   10
#define OLED_DC    11
#define OLED_CS    12
#define OLED_RESET 13
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
*/

// Uncomment this block to use hardware SPI
#define OLED_DC     6
#define OLED_CS     7
#define OLED_RESET  8
Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);

#define XPOS 0
#define YPOS 1
#define DELTAY 2

#define LOGO16_GLCD_HEIGHT 16 
#define LOGO16_GLCD_WIDTH  16 
static const unsigned char PROGMEM logo16_glcd_bmp[] =
{ B00000000, B11000000,
  B00000001, B11000000,
  B00000001, B11000000,
  B00000011, B11100000,
  B11110011, B11100000,
  B11111110, B11111000,
  B01111110, B11111111,
  B00110011, B10011111,
  B00011111, B11111100,
  B00001101, B01110000,
  B00011011, B10100000,
  B00111111, B11100000,
  B00111111, B11110000,
  B01111100, B11110000,
  B01110000, B01110000,
  B00000000, B00110000 };

#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif


void setup() {
  Serial.begin(9600);
  
  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC);
  // init done
  
  // Show image buffer on the display hardware.
  // Since the buffer is intialized with an Adafruit splashscreen
  // internally, this will display the splashscreen.
  display.display();
  delay(2000);

  // Clear the buffer.
  display.clearDisplay();

  // draw a single pixel
  display.drawPixel(10, 10, WHITE);
  // Show the display buffer on the hardware.
  // NOTE: You _must_ call display after making any drawing commands
  // to make them visible on the display hardware!
  display.display();
  delay(2000);
  display.clearDisplay();


 

}

void loop() {
  // put your main code here, to run repeatedly:
  display.clearDisplay();

  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println("Hello, Hardwareworld!");
  display.display();
  delay(2000);
  display.clearDisplay();

}

I have got the issue with hardware and software SPI so i don’t think that this is code related.

My display do not have got a RST pin, can it be that this is related to this? Is there a solution for this?

Thanks in advance!

The display needs to be driven by 3.3V logic levels. Use a logic level converter or resistors to drop the voltage. Alternatively run the Nano off 3.3V

thx for your reply.

I am using the 3.3 Volt pin of the nano, isn't this the same? Or how should i connect this?

What i found out is that i do not even have to connect the GND...

EDIT: Ah sorry I used google and saw that not only the voltage (VCC) is 3.3, right and the comminucation is still 5V.

should i just add a resistor on each line?

Example:
DISPLAY --------------- Nano
VCC ------------------ 3.3V Nano
GND ----------------- GND nano

DIN --------85Ohm resistor---------- SPI Data Line Pin
CLK--------85Ohm resistor---------- SPI Clock Line PIN
DC -------85Ohm resistor------ DATA PIN Nano

am I right?

85R is an unusual value. And it is VERY low.

You will probably be ok with 1k0 to 2k2 as series resistors.

As a silly question. I know this is an Arduino Forum rather than a Technical Forum. But did you learn about Ohm's Law when you were at school?

David.

hi, well i know the ohm law

U/R*I

learned a long time ago and just started learning again.

Well the thing is that i need to also translate in my language (i am from germany) :wink:

so you mean that i need a voltage divider right, for all lines/Pins? for example a 10k resistor to GND and to the line 4.7K?

thx in advance

4K7 and 10K should be fine providing the display is not already fitted with pullup resistors which would stop a good logic zero being reached.

I usually use 1K8 and 3K3 as the divider, or 1K2 and 2K2 because I have lots of those values.

ah ok, thank you... must i do this for all lines? SPI Data, SPI clock and DATA pin?

Yes, all output lines, e.g. data, clock, chip select and DC or RS line.

ok thank you!

Report back if this solves the problem!

Yes, a voltage divider is fine e.g. 4k7 + 10k.

If you use a voltage divider it will produce 3.3V logic from 5V logic.
It would only produce 2.2V logic if your AVR was running at 3.3V

Series resistors will work with a 5V AVR or a 3.3V AVR.
And you will be able to use them in both directions.

I know that your library probably does not read any pins. My libraries always try to read as well as write to the controller (if possible).

Series resistors rely on the chip substrate diodes conducting. The current is limited by the series resistors.
It is much better to run the AVR or ARM at 3.3V. Then you do not stress the substrate diodes. And you do not need any resistors at all.

David.

HI,

its me again, did all lines (except the 3.3V) with 4K7 and 10K without success, the display did not work in general.

What worked:
Keep SPI Lines directly connected.(Had do remove the divider on SPI lines.) Data Line is using the divider and removing the GND pin completely.
But its the same like if i do not use any divider... I have to remove the GND to get the Display working.

If I change something on the code like the Text it will stops working too :frowning:

Thank you in advance.

Frank

I do not believe you. 4k7 + 10k will multiply the 5V by 0.68 i.e. you get 3.4V

Have you made your "divider" with 10k + 4k7 ? i.e. you multiply by 0.32 getting 1.6V

This would clearly be too fierce.

You should find that simple 2k2 series resistors will work just fine. 1k0 will probably work too.
Other combinations of resistors can be used. Just keep within the order of magnutude used in the examples.

David.

Hi…

Tested this with 1k8 and 3k3 resistor… To make sure that I didn’t made something wrong. Same result. See attached picture.

Many Thanks.

Your photo looks like brown-green-red-gold i.e.1k5 5%
And orange-grey-orange-red-gold i.e. 383x100 = 38k3 5% which sounds unusual.

Only you can check the colour bands and read the value with a DMM.

David.

OK, I have had a closer look at the eBay advert and I see that there are level translator chips on the back of the board! These also feature in the blurred schematic although I cannot read the part numbers. This is unusual for a Chinese product! Can you tell me what codes are written on those chips?

So we can abandon the idea of using level translating resistors which is not a good idea when level translators are already in the circuit!.

Also the display appears to have a 5V to 3.3V regulator so you can power from 5V. So try this.

The board also has an R+C reset circuit. I have known cases where a proper reset is not generated if the supply comes up slowly. (This fits your symptoms as disconnecting ground and reconnecting it will reset the display chip). Connecting 5V tot he display VCC may help here as the displays 3.3V regulator will then not be in series with the Nano's 3.3V regulator so the supply rise time will probably increase.

More thoughts...

Try putting a 3 sec delay at the start of setup() e.g. delay(3000); This fixed a case here for an I2C OLED display, but you may not be having the same problem.

hi thanks to both of you.

@david:
checked both resistors, the values are 1k8 and 3k3.

@bodmer:
interesting! I will do some Pics if I am at home and will test the delay incl. the 5V line.

EDIT: found an picture for this display… attached for the internal pins from the display to the board. (attached)

2nd EDIT: found image of my display… same prints on the backside.

OK, it looks like 3 of the ICs near the signal pins are these level translators: "SN74LVC1G125 Single Bus Buffer Gate With 3-State Output". So that is good and you can drive them with 5V logic.

The 4th chip will most likely be the 5V to 3.3V regulator.

Hello,

thank you for your help. I did some tests now and the current behavior now is the same…

With GND attached it will only came up sporadic…

I change something in my testcode to get more output in the serial monitor:

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

/* 
// If using software SPI (the default case):
#define OLED_MOSI   9
#define OLED_CLK   10
#define OLED_DC    11
#define OLED_CS    12
#define OLED_RESET 13
Adafruit_SSD1306 display(OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
*/

// Uncomment this block to use hardware SPI
#define OLED_DC     6
#define OLED_CS     7
#define OLED_RESET  8
Adafruit_SSD1306 display(OLED_DC, OLED_RESET, OLED_CS);

#define XPOS 0
#define YPOS 1
#define DELTAY 2

#define LOGO16_GLCD_HEIGHT 16 
#define LOGO16_GLCD_WIDTH  16 
static const unsigned char PROGMEM logo16_glcd_bmp[] =
{ B00000000, B11000000,
  B00000001, B11000000,
  B00000001, B11000000,
  B00000011, B11100000,
  B11110011, B11100000,
  B11111110, B11111000,
  B01111110, B11111111,
  B00110011, B10011111,
  B00011111, B11111100,
  B00001101, B01110000,
  B00011011, B10100000,
  B00111111, B11100000,
  B00111111, B11110000,
  B01111100, B11110000,
  B01110000, B01110000,
  B00000000, B00110000 };

#if (SSD1306_LCDHEIGHT != 32)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

String str ="Hello World!";

void setup() {
  delay(3000);
  Serial.begin(9600);

  //Commandline Output
 Serial.println("\n\nInsert Text:");

  
  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC);
  // init done
  // Show image buffer on the display hardware.
  // Since the buffer is intialized with an Adafruit splashscreen
  // internally, this will display the splashscreen.
  display.display();
  delay(2000);

  // Clear the buffer.
  display.clearDisplay();

  // draw a single pixel
  display.drawPixel(10, 10, WHITE);
  // Show the display buffer on the hardware.
  // NOTE: You _must_ call display after making any drawing commands
  // to make them visible on the display hardware!
  display.display();
  delay(2000);
  display.clearDisplay();


 

}

void loop() {

//SERIAL COMMANDLINE 
if(Serial.available() > 1)
    {
        str = Serial.readStringUntil('\n');
        Serial.println("New Text will be:");
        Serial.println(str);
    }
   
  
  //DISPLAY CODE:
  display.clearDisplay();  
  display.setTextSize(1.2);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println(str);
  display.display();
  delay(1000);
   Serial.println("\nLooping...");

}

So i can see if the code is working and I can change the output etc…

Seems like there is something not working correctly… if the display came up correctly i can see the adafruit logo, the small pixel at 10,10 and after that a “Hello World!” But if the loop cycle comes up, the screen will not cleared completely and the text will scrumbled up and the scrumble will change every loop.

See attached pic. Looks like the display does not clear the cache, or buffer or other stuff.

Is there a soft reset possible? Or any other idea?