Large oled display wont start

Hello, this is Josh Sparber. One of the modules I am building has a 1.91 inch New Haven oled. I have vetted the program as much as I can. After months of working on this it still does not work. I am using SPI 4 wire on the Arduino Due and I have connected the main inputs to the SPI plug in the middle of the Arduino Due board. Just to initiate my basic design I have a test file that checks to see if the oled can cover the screen in green pixels. I have a description of my connections in the program itself, including the recommended connections for BS0, BS1, and BS2.

If you are a trained and working engineer I would pay for your help. I will email you my test file from jsparbear5@gmail.com. No phonies, please.

Hello @joshalunio

Welcome.

I doubt that you will get much help with your problem because you have provided very little information. Please read the forum guide, which tells you everything you need to tell us to stand a chance of getting reasonable help. There is a link to the guide at the top of every forum category.

Thank you

Welcome!
I can understand your frustration but without more information we can only take a guess and the odds favor us being wrong. We would like to help, however considering we cannot see or touch your project you need to help us help you. Post an annotated schematic showing exactly how you have wired it including power sources. Post your code using < CODE > tags. Post links to the technical information on the hardware such as the New Haven oled.

Datasheet: https://newhavendisplay.com/content/specs/NHD-1.91-176176B.pdf
See Page6 for I2C/SPI pins
See Page 7 for Electrical Characteristics.
See Page 7 for SSD1333 Controller (or this link)

My hardware wiring settings are posted in the file itself.
A photo of a bunch of wired up stuff is probably not helpful.
I have followed all the advice, USB micro B jack into the plug near the 5 Volt plug in,
wired inputs from the SPI plug in the middle of the Arduino Due board.
The Arduino board itself is likely OK, because I went back and attached it
to the 1306 oled, the smaller one, and the 1306 oled worked fine.
My oled stays dark, which is the normal backgrounding for the display.
So something is not being excited.
I have tried grounding all the inputs that the 1.91 inch oled does not use,
and that did not change anything.
Previously, I went through another wiring, and when I lifted up the ground and put it back in again, I got the screen to paste several colors across itself: green, red, and mixed.
So it is likely the 1.91 inch oled is alive.

Tried several power inputs.

Code for the test file is here.
Thanks in advance for your support.

type or paste code here
```// Section 1, fetching libraries, and setting pre-compiler attributes
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1351.h>
#include <SPI.h>

// Screen dimensions
#define SCREEN_WIDTH  176
#define SCREEN_HEIGHT 176

// oled address
#define SCREEN_SPI_ADDRESS 0x3C


// Color definitions
const unsigned short BLACK  = 0x0000;
const unsigned short BLUE  =  0x001F;
const unsigned short GREEN  = 0x07E0;
const unsigned short RED  = 0xF800;
const unsigned short WHITE = 0xFFFF;
const unsigned short VIOLET = 0x781F;
const unsigned short YELLOW = 0xFFE0;

/*

Arduino SPI communication uses 
a) 4 wires—SCK (Clock), 
b) MOSI (Master Out), 
c) MISO (Master In), 
d) and CS/SS (Chip Select)—to exchange data at high speeds. 
The SPI.h library manages communication, requiring 
a) SPI.beginTransaction() for settings (not shown), 
b) digitalWrite() to manage the CS pin (multiple times), 
c) and SPI.transfer() to send/receive bytes (not shown). 

*/


// SPI Pin connections 
#define OLED_RST    8 // Arduino Due pin D8 to oled pin 16
#define OLED_DC     9 // Arduino Due pin D9 to oled pin 4
#define OLED_CS    10 // Arduino Due pin D10 to oled pin 17
#define OLED_MOSI  77 // Arduino Due SPI header pin 77 (known as SPI-4) to oled pin 8
#define OLED_CLK   76 // Arduino Due SPI header pin 76 (known as SPI-3) to oled pin 7
// Recommended for SPI-4 Wire: BS1 (pin 19) is VCC, BS0, BS2 (pins 18, 20) are GND




/*  configuration of six pin SPI header

  RST-78 (pin 5)---SCLK 76 (pin 3)---MISO--74 (pin1) 
  |                                                |
  |                                                |
  GND-79 (pin 6)---MOSI-77 (pin 4)-----5V-75 (pin 2)   

  MISO is not used in this configuraton
  5V is not used in this configuraton
  
*/

// Initialize display
Adafruit_SSD1351 oled = Adafruit_SSD1351(SCREEN_WIDTH, SCREEN_HEIGHT,&SPI,OLED_DC,OLED_RST,OLED_CS);

// Section 2, prepping oled and attributes to get ready for display

 
void setup() {
  
  pinMode(OLED_CS,OUTPUT);
  pinMode(OLED_DC,OUTPUT);
  pinMode(OLED_RST,OUTPUT);

  SPI.begin(OLED_CS);
  SPI.beginTransaction(SPISettings(8000000, MSBFIRST,SPI_MODE0));
  
  // the reset pulse is needed to initiate the display for inputs,
  // below is the recommended timing, 10 us as low (3 to 10 us, 
  // 100 us still OK, 20 ms as high (15 to 20 ms)
  
  digitalWrite(OLED_RST, LOW);
  delay(.01);
  digitalWrite(OLED_RST, HIGH);
  delay(20);

  // below commands protect setup commands as given

  digitalWrite(OLED_DC,LOW);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0xFD);
  digitalWrite(OLED_CS, HIGH);
  
  digitalWrite(OLED_DC,HIGH);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0x12);
  digitalWrite(OLED_CS, HIGH); 
  
 
 // SPI.transfer(0x12); frees commands to be open to display changes
 // SPI.transfer(0xFD); command Lock, step one to lock in setup commands
 // SPI.transfer(0x16); locks command to prevent display changes,step two 
 // to keep setup commands locked,see below
 // SPI.transfer(0xAE); display OFF

// Set remaining oled attributes
  
// Clock divider,0x09 is default, sets spanning rate

  digitalWrite(OLED_DC,LOW);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0xB3);
  digitalWrite(OLED_CS, HIGH);
  
  digitalWrite(OLED_DC,HIGH);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0x09);
  digitalWrite(OLED_CS, HIGH); 

// Contrast, 256 levels of contrast
  
  digitalWrite(OLED_DC,LOW);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0xC1);
  digitalWrite(OLED_CS, HIGH);
  
  digitalWrite(OLED_DC,HIGH);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0x3F);
  digitalWrite(OLED_CS, HIGH); 
  
 // Current, 0x0F is optimum, 0x01 to 0x07 is low for night mode, 
 //0x07 to 0x10 for maximum
 
  digitalWrite(OLED_DC,LOW);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0xC7);
  digitalWrite(OLED_CS, HIGH);
  
  digitalWrite(OLED_DC,HIGH);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0x01);
  digitalWrite(OLED_CS, HIGH); 

 // Communication voltage, 0x05 is .82*VCC
  
  digitalWrite(OLED_DC,LOW);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0xBE);
  digitalWrite(OLED_CS, HIGH);
  
  digitalWrite(OLED_DC,HIGH);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0x20);
  digitalWrite(OLED_CS, HIGH); 

 // Multiplex ratio,this determines how many rows are 
 //scanned at a time, 0xAF is a 1:176 ratio, or 
 //one row per scan, the default
  
  digitalWrite(OLED_DC,LOW);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0xCA);
  digitalWrite(OLED_CS, HIGH);
  
  digitalWrite(OLED_DC,HIGH);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0xAF);
  digitalWrite(OLED_CS, HIGH); 

 // Phase length, pre-charge period,and pre-charge voltage
 // are implemented with defaults as shown below 
 // for the display controller (SSD1333)
  
  digitalWrite(OLED_DC,LOW);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0xB1);
  digitalWrite(OLED_CS, HIGH);
  
  digitalWrite(OLED_DC,HIGH);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0x84);
  digitalWrite(OLED_CS, HIGH); 
 
 // Pre-charge period, 0x08 is 8 display clocks
   
  digitalWrite(OLED_DC,LOW);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0xB6);
  digitalWrite(OLED_CS, HIGH);
  
  digitalWrite(OLED_DC,HIGH);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0x08);
  digitalWrite(OLED_CS, HIGH); 

 // Pre-charge voltage, default is 0x17,or.40*VCC
   
  digitalWrite(OLED_DC,LOW);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0xBB);
  digitalWrite(OLED_CS, HIGH);
  
  digitalWrite(OLED_DC,HIGH);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0x17);
  digitalWrite(OLED_CS, HIGH); 
  
 // Re-map enables the map to be flipped:
 // 0x64 is normal, 0x14 or 0x06 allows 180 degree flip
 // Re-map color depth,selects between two color modes,
 // 16 bit (65K options) and 18 bit (enhanced color, 262K options)
 // 0x50 is default
  
  
  digitalWrite(OLED_DC,LOW);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0xA0);
  digitalWrite(OLED_CS, HIGH);
  
  digitalWrite(OLED_DC,HIGH);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0x64);
  digitalWrite(OLED_CS, HIGH); 

  digitalWrite(OLED_DC,LOW);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0xA0);
  digitalWrite(OLED_CS, HIGH);
  
  digitalWrite(OLED_DC,HIGH);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0x50);
  digitalWrite(OLED_CS, HIGH); 
 
 // Set Column Address, 0x00 start, 0xAF end, per spec
  
  digitalWrite(OLED_DC,LOW);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0x15);
  digitalWrite(OLED_CS, HIGH);
  
  digitalWrite(OLED_DC,HIGH);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0xAF);
  digitalWrite(OLED_CS, HIGH); 

  digitalWrite(OLED_DC,LOW);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0x15);
  digitalWrite(OLED_CS, HIGH);
  
  digitalWrite(OLED_DC,HIGH);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0x00);
  digitalWrite(OLED_CS, HIGH); 
    
 // Set Row Address, 0x00 start, 0xAF end, per spec
  
  digitalWrite(OLED_DC,LOW);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0x75);
  digitalWrite(OLED_CS, HIGH);
  
  digitalWrite(OLED_DC,HIGH);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0xAF);
  digitalWrite(OLED_CS, HIGH); 

  digitalWrite(OLED_DC,LOW);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0x75);
  digitalWrite(OLED_CS, HIGH);
  
  digitalWrite(OLED_DC,HIGH);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0x00);
  digitalWrite(OLED_CS, HIGH); 
  
/*  

clock divider ratio: B3 with the following, according to NH doc 
A[3:0] => Display Clock Divider
A[7:4] => Oscillator Frequency
column address: 15
command lock: FD based on NH doc
contrast (set): 81, C1 based on NH doc
display offset: A2
display (on/off): AE to AF
display start line (set): A1
memory addressing mode: 20
multiplex ratio: A8, CA based on NH doc
oscillator frequency: B3
pre-charge: VCOMH: BE
pre-charge period: B1, B6 according to NH doc
ram (display): A4 to A7
remap: A0
row address: 75
scroll (stop): 2E
scroll (vertical/horizontal): 26 to 27, A1 and A2 according to NH doc

*/

  

 //  Turn on display, this is recommended to be the last step in the setup process
  
  digitalWrite(OLED_DC,LOW);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0xAF);
  digitalWrite(OLED_CS, HIGH);
  
  digitalWrite(OLED_DC,HIGH);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0xA5);
  digitalWrite(OLED_CS, HIGH); 
  
  
 /*
 
 0xAF = Display ON command
 Set Display Mode
 Default => 0xA6
 0xA4 => Entire Display Off, All Pixels Turn Off, 
 used to return display to original mode
 0xA5 => Entire Display On, All Pixels Turn On at GS Level 63, 
 maximum brightness, used to check for dead pixels
 0xA6 => Normal Display
 0xA7 => Inverse Display

 */
  
}
        

  
// Section four, looping program to draw line

void loop() {

  // SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));

  
  // set column address, low and high
  
  digitalWrite(OLED_DC, LOW);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0x15);
  SPI.transfer(0x00);
  SPI.transfer(0xAF);
  digitalWrite(OLED_CS, HIGH);

   
  // set row address, low and high
  
  digitalWrite(OLED_DC, LOW);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0x75);
  SPI.transfer(0x00);
  SPI.transfer(0xAF);
  digitalWrite(OLED_CS, HIGH);

   
  // send color data to RAM
  
  SPI.transfer(OLED_CS, 0xD3, SPI_CONTINUE); // Set Display Offset
  SPI.transfer(OLED_CS, 0x00, SPI_CONTINUE); // Set Offset Value
  
  digitalWrite(OLED_DC, LOW);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0x5C);
  digitalWrite(OLED_CS, HIGH);

  // sending data to RAM, send high byte, then low byte

  digitalWrite(OLED_DC, HIGH);
  digitalWrite(OLED_CS, LOW);
     for (int i = 0; i < 176*176; i++){
       SPI.transfer(GREEN >> 8); 
       SPI.transfer(GREEN & 0xFF); 
       }
  digitalWrite(OLED_CS, HIGH);

 
 }  


YT, Joshua H. Sparber

Thank you for posting your code.

If you are not having an issue, sure. If you are having an issue, post what is asked.

You missed this...

Run the Arduino I2C scanner to verify this address is correct.

You need to draw by hand where every wire starts and ends. Not words, not instructions, look and draw. Photos are almost never usable, but adding them may be of some limited use.

Maybe my micro B jack was not in far enough. I did see the oled work this much: I can turn off the oled display, to obtain a full black screen (instruction 0A4), a full white screen (0A5), and a full mixed screen (0A6). I don't think my wiring is messed up. I vetted several times, and the available information is a murky mess. I spent a lot of time breadboarding in my life. However, I still cannot get it to paint pixels for me. The following is my coding for it to do this:

 //the other part of the code has not changed

// Section 1, fetching libraries, and setting pre-compiler attributes
// Convert 24-bit RGB to 16-bit RGB565

uint16_t color565(uint8_t r, uint8_t g, uint8_t b) {
  return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
  }

const uint16_t BLACK  = 0x0000;
const uint16_t BLUE  =  0x001F;
const uint16_t GREEN  = 0x07E0;
const uint16_t RED  = 0xF800;
const uint16_t WHITE = 0xFFFF;
const uint16_t VIOLET = 0x781F;
const uint16_t YELLOW = 0xFFE0;

//added

  SPI.transfer(OLED_CS, 0xA2, SPI_CONTINUE); // Set Display Offset
  SPI.transfer(OLED_CS, 0x00, SPI_CONTINUE); // Set Offset Value
  
 
 0xAF = Display ON command
 Set Display Mode
 Default => 0xA6
 0xA4 => Entire Display Off, All Pixels Turn Off, 
 used to return display to original mode
 NB: normal mode is a black screen
 0xA5 => Entire Display On, All Pixels Turn On at GS Level 63, 
 maximum brightness, used to check for dead pixels;
 NB: this is a solid white screen
 0xA6 => Normal Display
 NB: this is a mishmash of colors
 0xA7 => Inverse Display

 */
    
void setup ();
{

uint16_t color565(uint8_t r, uint8_t g, uint8_t b) {
  return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
  }

const uint16_t BLACK  = 0x0000;
const uint16_t BLUE  =  0x001F;
const uint16_t GREEN  = 0x07E0;
const uint16_t RED  = 0xF800;
const uint16_t WHITE = 0xFFFF;
const uint16_t VIOLET = 0x781F;
const uint16_t YELLOW = 0xFFE0;

//rest has not changed

}

     
 void loop() {

//rest has not changed


 digitalWrite(OLED_DC, LOW);
  digitalWrite(OLED_CS, LOW);
  SPI.transfer(0x5C);
 
// sending data to RAM, send high byte, then low byte
  
  uint8_t x; 
  uint8_t y;
  x = (color565(255,0,255)) >> 8;
  y = (color565(255,0,255)) & 0xFF;
  digitalWrite(OLED_DC, HIGH);
  digitalWrite(OLED_CS, LOW);
      for (int i = 0; i < 176*176; i++){
      // High byte, Low byte
      SPI.transfer(x); 
      SPI.transfer(y); 
      SPI.transfer(SPI_CONTINUE); 
      }
   digitalWrite(OLED_CS, HIGH);
}


This sketch does not compile for many reasons.

Where is

  tft.begin();

Did you try the example sketch in the Library?