BuyDisplay.com 3.2" OLED (SSD1322) + Arduino Mega + HW SPI + u8g2 library

Hello,

I seem to be having trouble getting my OLED display to work using HW SPI. To test I am using the "Hello World" program in the u8g2 library examples (full buffer) using the software SPI first.

Uncommenting this constructor:

U8G2_SSD1322_NHD_256X64_F_4W_SW_SPI u8g2(U8G2_R0, /* clock=/ 52, / data=/ 51, / cs=/ 53, / dc=/ 49, / reset=*/ 48); // Enable U8G2_16BIT in u8g2.h

The SW SPI works flawlessly, but I want to try and get HW SPI working for speed reasons.

When I swap to this constructor:

U8G2_SSD1322_NHD_256X64_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=/ 53, / dc=/ 49, / reset=*/ 48); // Enable U8G2_16BIT in u8g2.h

It doesn't work at all (just a blank screen).

Things I've done:

  • Used a logic level converter module (for 4 of the 5v signals and used a 4.7K resistor for the fifth wire to be dropped down to 3.3v)

  • Enabled U8G2_16BIT in u8g2.h

  • Checked the pins_arduino.h file to determine default HW pins for SPI using a Mega. Found the following:


#define PIN_SPI_SS (53)

#define PIN_SPI_MOSI (51)

#define PIN_SPI_MISO (50)

#define PIN_SPI_SCK (52)

static const uint8_t SS = PIN_SPI_SS;

static const uint8_t MOSI = PIN_SPI_MOSI;

static const uint8_t MISO = PIN_SPI_MISO;

static const uint8_t SCK = PIN_SPI_SCK;


I don't have any pin on the display connected to MISO pin 50 as I don't know if it needs it or not? and wouldn't know what to connect it to as nothing looked to be obviously labelled for MISO

Can anyone suggest other things for me to try? I've used other smaller displays with Unos and they work flawlessly using the u8g2 lib using HW SPI. This is the only one i've had trouble with so far.

I am a beginner to Arduino with about 6 months experience so I apologise if i've missed something obvious

Cheers,
Adam

From the Wiki:
U8G2_SSD1322_NHD_256X64_F_4W_HW_SPI(rotation, cs, dc [, reset]) [full framebuffer, size = 2048 bytes]

which means that your HW constructor looks fine

U8G2_SSD1322_NHD_256X64_F_4W_HW_SPI u8g2(U8G2_R0, 53, 49, 48); // Enable U8G2_16BIT in u8g2.h

Have you enabled U8G2_16BIT ?

Yes, it is very wise to try the 4W_SW_SPI constructor first.
Since you have verified the HW pins for SCK, MOSI it should run on HW_SPI

I don't have a SSD1322. But Oliver's constructors should work 100%.

Hi David,
Yep, I mentioned previously that I have enabled U8G2_16BIT in u8g2.h.. I actually didn't mention in the first post that I had made another program that proved I could print the entire length of the screen in SW SPI.
Do you think it might be worth switching SPI modes? I assume by default its running SPIMODE0.
Cheers,
Adam

I've been trying many things. Firstly, I've been playing with my own program to demonstrate the full width of the screen.

I managed to get a "bad" image appearing when using the ICSP pins 3 and 4 (for clk and data respectively) instead of pins 52 and 51 when switching to the HW SPI constructor.

I've tried all SPI modes and get roughly the same image as the bad looking image.

I am only allowed to post 1 image per post so here is a side by side image, showing the good and bad image using SW and HW SPI.

Most controllers will work in SPI #0 or SPI #3 modes. I would stick with #0.
The 3x2 SPI connector contains digital #50, #51, #52. i.e. male versions of 50, 51, 52 on the female 18x2 header.
If SW SPI was working with your wiring so will HW SPI.

The SSD1322 data sheet calls it a "480x128 controller with grayscale."
But the addressing paragraph implies 128 rows of 240 (4-bit) pixels.

Your photos imply that the HW constructor works but not showing the rows properly.

Oliver only supports monochrome. But the HW_SPI should work the same as SW_SPI. I would stick with SW_SPI for the moment. It works.
Oliver will probably comment within a few days.

David.

Hi David,
I've just worked out Oliver is the creator of the library :slight_smile: silly me.. hope he is able to help me.
Cheers,
Adam

Have you tried the BuyDisplay example code?
This uses HW SPI. It has simple functions for displaying mono or grayscale bitmaps. It can display text.

I still reckon that U8g2lib should behave exactly the same for HW_SPI as SW_SPI.

David.

No I haven't tried it. You're right i'll give that a shot and at least confirm that works. Cheers,

Hi David,
I had a chance to experiment just now. I ran the example ER code that has its own library (er_oled). This worked flawlessly once I changed my DC, reset and CS pins to 9, 8 and 10 respectively.

I then went back to using U8G2 in my application, changing the SW and HW constructors to use DC, reset and CS pin as mentioned above. Again the SW SPI constructor works, but the HW SPI constructor doesn't.

Could it be the order of the parameters maybe? Different between HW and SW constructor? I know we have established its cs, dc, reset but I wonder if this really the case?

/***************************************************
//Web: http://www.buydisplay.com
EastRising Technology Co.,LTD
Examples for ER-OLEDM032-1
Display is Hardward SPI 4-Wire SPI Interface
Tested and worked with:
Works with Arduino 1.6.0 IDE
Test OK : Arduino DUE,Arduino mega2560,Arduino UNO Board
****************************************************/

/*
Note:The module needs to be jumpered to an SPI interface. R19,R21 Short and R18,R20 Open
Unused signal pin Recommended to connect to GND
== Hardware connection ==
OLED => Arduino
*1. GND -> GND
*2. VCC -> 3.3
*4. SCL -> SCK
*5. SDI -> MOSI
*14. DC -> 9
*15. RES -> 8
*16. CS -> 10
*/

#include <SPI.h>
#include "er_oled.h"

//uint8_t oled_buf[OLED_Y_MAXPIXEL * OLED_X_MAXPIXEL/2];

void setup() {
Serial.begin(9600);
Serial.print("OLED Example\n");

/* display an image of bitmap matrix */
er_oled_begin();
er_oled_clear();
er_oled_bitmap_gray(PIC1);
delay(3000);

er_oled_clear();
er_oled_bitmap_gray(PIC2);
delay(3000);

er_oled_clear();
er_oled_bitmap_mono(PIC3);
delay(3000);

er_oled_clear();
er_oled_string(0, 0, "",0);
er_oled_string(32, 16, "EastRising Technology", 0);
er_oled_string(40, 32, "www.buydisplay.com", 1);
er_oled_string(0, 48, "
",0);
uint8_t i;
for(i=0;i<=48;i++)
{
command(0xa1); //start line
data(i);
delay(100);
}
for(i=48;i>0;i--)
{
command(0xa1); //start line
data(i);
delay(100);
}

}

void loop() {

}

Cheers,
Adam

Obviously you must use the hardware SPI pins on Uno, Mega, Due, ... i.e. MOSI and SCK which you always find on the 3x2 SPI header.

You can use any GPIO pins for CS, DC, RST

Be patient. I expect that Oliver might reply on this Forum when he has some time.

Otherwise you can post an Issue on the U8g2 GitHub. Write a trivial program that demonstrates the SW / HW difference and attach the photos.

I displayed PIC1, PIC2, PIC3 (in 4-bit grayscale) on a colour TFT. Grayscale images can look quite nice.

Hi All, just an FYI in case someone else runs into this problem. I have been talking with Oliver, and for my case with this particular display, I had to set the bus speed.

u8g2.setBusClock(1900000). Through trial and error of setting speeds, this seems to be the highest im able to set it to successfully using the HW SPI constructor :slight_smile:

Cheers!

I am gobsmacked. SPI @ 1.9MHz !!

Other Solomon OLED controllers are happy with 8MHz SPI and 400kHz I2C.

Many TFT controllers are happy with > 40MHz SPI

Anyway, I am pleased that you have it working now.

It is nice to display grayscale photos and logos. I suppose this is less important for a 256x64 than for a 128x128 panel.

David.

Yeah look I don't know a great deal about performance of displays - this one isn't sounding like the Ferrari of displays lol. My project is related to digitising some car gauges. Most things like temps etc. are fine with a slow refresh but RPM will need to be somewhat reasonably fast. I will see how it goes. I don't really care about greyscale for my application. All I was wanting was a larger screen and picked this one purely for its form factor - 3.2 inch - so fits perfectly with the circular shape gauge its replacing. Thanks for you help along the way David :slight_smile: Cheers,