NHD-0420DZW-AB5 OLED Display incorrect output

Hey guys!

I’ve been working with the particle photon for a while and wanted to set up a display now.
For this, I’ve bought the NHD-0420DZW-AB5 and tried to use the ported https://github.com/kbgg/Adafruit_CharacterOLED lib. I’ve set up wiring (4 bit mode, using pins D1 to D7), but even the example does not really seem to work. The code finishes the “begin” method, but doesn’t seem to clear the screen or anything. Whenever I run any .print method, the Particle goes into an endless loop within the waitForReady method. Also, sometimes, random symbols appear on the screen or move.

My wiring is set up as follows:
(1) VSS -> 5V
(2) VDD -> Ground
(4) RS -> D7
(5) R/W -> D6
(6) E -> D5
(7-10) DB4 - DB7 -> D4-D1

Anything I can do?

Kind regards,
ohaz

So you object instantiation looks like this?

Adafruit_CharacterOLED lcd(OLED_V2, D7, D6, D5, D4, D3, D2, D1);

If so and it still doesn't work try putting RS to D0 - maybe the LED on D7 keeps the device reset.
Also make sure the display does work with 3.3V logic when powered off Vin (5V).

BTW, there was a similar thread not long ago

Yes, my instantiation looks like this. I’ve already tried switching away from D7 (it’s now lcd(OLED_V2, D6,D5,D4,D3,D2,D1,D0); ) but that didn’t help either. I’ve also figured out that when working on 5V the 3V3 logic won’t work, so I’ve connected the display to the particles power supply. Still nothing.

To test if the display works, I’ve set it up on an arduino, same library (the original arduino one), works like a charm. I want to get it to work on the particle though.

I’m not running I2C, so the other thread sadly does not really help.

What do you mean by that?
Are you powering the display now off the 3V3 pin?

I’ve tried both - powering the display using 5V and the 3V3 supply of the particle. The 5V external source has the problem, that the display then requires ~4.6V edges, which the 3V3 pins of the particle can’t supply.

Currently, the display is powered by the particle. Still doesn’t work.

Are you running the sample code of the lib or your own?
You could remove the WiFi/cloud impact for testing by using SYSTEM_MODE(MANUAL)
You’d just need to put the device into Safe Mode to reflash OTA after that.

I’m running the sample code of the lib (except for initalizing it with 20/4 symbols/rows instead of 16/2). I’ve tried disabling Cloud impact (Particle.disconnect()), I’ve also tried using MANUAL mode.

I’ve used an oscilloscope to test outputs of the pins. Apparently, the Particle Photon seems to send of random gibberish on a lot of pins until it is finished booting. Perhaps that “confuses” the display?

That could be since on bootup some of the D-pins are used for JTAG and hence get pull resistors temporarily attached.
But resetting the display should help undo any impact of that on the display.
Alternatively you could use the A-pins A0~A7 as long you make sure A3 & A6 (DAC) don't exceede 3.3V at any time.
As long you don't use Serial1 you can even repurpose the RX/TX pins.

And you could try OLED_V1 too.


Update:
I've just seen something puzzling in the lib.
I thought the reset pin was active low, but the library keeps pulling it low virtually permanently.
Only void Adafruit_CharacterOLED::send(uint8_t value, uint8_t mode) may push it high.
I'm not sure whether this is meant to be - unless the rs pin is not actually meant to be connected to reset but rather to what's commonly called the D/C pin on other displays.

Update 2:
Yup, the class definition features this line

  uint8_t _rs_pin; // LOW: command.  HIGH: character.

That's some odd naming there D/C would stand for Data/Command but rs is bound to be taken for reset IMHO.

Update 3:
After looking up the DZW datasheet I realised rs stands for register select and there is no reset pin.
On the CW displays there is a D/C pin and a RES/.
So the wiring should be OK as you've got it.

But you could play with the jumper settings shown on page 4 in the datasheet.
I'm not sure if you want 6800-MPU Parallel or 8080-MPU Parallel

I got it to work. Somehow. Here’s a list of changes I did, one of them did the trick, maybe a combination of them. I’ll figure out which one it was afterwards:

  • Use A3,A5,A6,A0,A1,A2,A4 as pins (in constructor order)
  • Use OLED_V2 (this can’t be the only reason it works, have tried this one before)
  • Remove the begin(16,2); in the init method of the OLED lib (same as above, can’t be the only reason)
  • In the begin method, before the “Put back to 8-bit mode” line, I added command(0x08); delayMicroseconds(5000); command(0x01); delayMicroseconds(5000); This turns off the display and then clears it.

After these steps, the display worked.

Thank you so much for your help!

Edit: I did not have to change jumper settings!

Glad to hear :+1:

Judging by the type of your display this should be lcd.begin(20,4) anyway.

Yeah, I really don’t understand why this line is in the init method of the lib. Definitely the wrong place for it. It’s also wrong in the arduino lib