Apologies @ScruffR. I’ll attach my code below which has my pin config for the photon and the display. The datasheet for my display is NHD-0420CW-AG3 I’ve followed the instructions in the datasheet on pg 4-5 and “I think” I’ve interpreted them right … but not totally sure… like /RES… I have that tied high… should it be low and on some posts I’ve seen that you need pull-up resistors on SDA/SCL pins. I’ve seen some folks use 4.7K ohm or 10K ohm tied to 3.3V. Then finally docs say 2.8V ~ 5V… is 3.3V ok or do I need to convert to 2.8V or 5V explicit.
/*
* from Demo_NHD0420CW-Ax3_I2C.ino
*
* Tutorial sketch for use of character OLED slim display family by Newhaven with Arduino Uno (Brian Beardmore: modifying for Particle Photon), using
* only Wire (I2C) library. Models: NHD0420CW-Ax3, NHD0220CW-Ax3, NHD0216CW-Ax3. Controller: US2066
* in this example, the display is connected to Photon via I2C interface.
*
* Displays on the OLED alternately a 4-line message and a sequence of character "block".
* This pgm ssumes the use of a 4x20 display; if different, modify the values of the two variables
* ROW_N e COLUMN_N.
* The pgm uses the minimum possible of Photon pins; if you intend to use also /RES line,
* the related instructions are already present, it's sufficient to remove the comment markers.
*
* The circuit modified by Brian Beardmore for Particle Photon I2C:
* OLED pin 1 (Vss) to VSS ground
* OLED pin 2 (VDD) to 3.3V
* OLED pin 3 (REGVDD) to GND (not using 5V, docs say take to GND)
* OLED pin 4 (SA0) to VSS ground should use 0x3C address (to assign I2C address 0x3D, connect to VDD)
* OLED pin 5 and 6 to VSS ground
* OLED pin 7 (SCL) to Photon D1 (SCL); 10K pull-up resistor on OLED pin to 3.3V? Do I need this?
* OLED pin 8 and 9 (SDAin,SDAout are jumpered) to Photon D0 (SDA); 10K pull-up resistor on each OLED pin 8 and 9 to 3.3V? Do I need this?
* OLED pin 10 to 15 to VSS ground
* OLED pin 16 (/RES) to VDD 3.3V
* OLED pin 17 (BS0) to VSS ground ** I2C config BSO to GND (low)
* OLED pin 18 (BS1) to VDD 3.3V ** I2C condig BS1 to 3.3V (high)
* OLED pin 19 (BS2) to Vss ground ** I2C config Bs2 to GND (low)
* OLED pin 20 (Vss) to Vss ground
*
* Original example created by Newhaven Display International Inc.
* Modified and adapted to Arduino Uno 15 Mar 2015 by Pasquale D'Antini
* Modified 19 May 2015 by Pasquale D'Antini
* Modified 06 Feb 2017 by Brian Beardmore for Particle Photon
*
* This example code is in the public domain.
*/
#include <application.h> // added for Photon support
const byte ROW_N = 4; // Number of display rows
const byte COLUMN_N = 20; // Number of display columns
//const byte RES = 13; // Arduino's pin assigned to the Reset line (optional, can be always high)
const byte SLAVE2W = 0x3C; // Display I2C address, in 7-bit form: 0x3C if SA0=LOW, 0x3D if SA0=HIGH
const byte TEXT[4][21] = {"1-Newhaven Display--",
"2-------Test--------",
"3-16/20-Characters--",
"4!@#$%^&*()_+{}[]<>?"}; // Strings to be displayed
byte new_line[4] = {0x80, 0xA0, 0xC0, 0xE0}; // DDRAM address for each line of the display
byte rows = 0x08; // Display mode: 1/3 lines or 2/4 lines; default 2/4 (0x08)
byte tx_packet[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
// Packet to be transmitted (max 20 bytes)
// _______________________________________________________________________________________
void command(byte c) // SUBROUTINE: PREPARES THE TRANSMISSION OF A COMMAND
{
tx_packet[0] = 0x00; // Control Byte; C0_bit=0, D/C_bit=0 -> following Data Byte contains command
tx_packet[1] = c; // Data Byte: the command to be executed by the display
send_packet(2); // Transmits the two bytes
}
// _______________________________________________________________________________________
void data(byte d) // SUBROUTINE: PREPARES THE TRANSMISSION OF A BYTE OF DATA
{
tx_packet[0] = 0x40; // Control Byte; C0_bit=0, D/C_bit=1 -> following Data Byte contains data
tx_packet[1] = d; // Data Byte: the character to be displayed
send_packet(2); // Transmits the two bytes
}
// _______________________________________________________________________________________
void send_packet(byte x) // SUBROUTINE: SEND TO THE DISPLAY THE x BYTES STORED IN tx_packet
{
byte ix = 0; // Bytes index
Wire.beginTransmission(SLAVE2W); // Begin the transmission via I2C to the display with the given address
for(ix=0; ix<x; ix++) // One byte at a time,
{
Wire.write(tx_packet[ix]); // queue bytes for transmission
}
Wire.endTransmission(); // Transmits the bytes that were queued
}
// _______________________________________________________________________________________
void output(void) // SUBROUTINE: DISPLAYS THE FOUR STRINGS, THEN THE SAME IN REVERSE ORDER
{
byte r = 0; // Row index
byte c = 0; // Column index
command(0x01); // Clears display (and cursor home)
delay(2); // After a clear display, a minimum pause of 1-2 ms is required
for (r=0; r<ROW_N; r++) // One row at a time,
{
command(new_line[r]); // moves the cursor to the first column of that line
for (c=0; c<COLUMN_N; c++) // One character at a time,
{
data(TEXT[r][c]); // displays the correspondig string
}
}
delay(2000); // Waits, only for visual effect purpose
for (r=0; r<ROW_N; r++) // One row at a time,
{
command(new_line[r]); // moves the cursor to the first column of that line
for (c=0; c<COLUMN_N; c++) // One character at a time,
{
data(TEXT[3-r][c]); // displays the correspondig string (in reverse order)
}
}
}
// _______________________________________________________________________________________
void blocks(void) // SUBROUTINE: FILLS THE ENTIRE DISPLAY WITH THE CHARACTER "BLOCK"
{
byte r = 0; // Row index
byte c = 0; // Column index
command(0x01); // Clear display (and cursor home)
delay(2); // After a clear display, a minimum pause of 1-2 ms is required
for (r=0; r<ROW_N; r++) // One row at a time,
{
command(new_line[r]); // moves the cursor to the first column of that line
for (c=0; c<COLUMN_N; c++) // One character at a time,
{
data(0xDB); // displays the character 0xDB (block)
delay(50); // Waits, only for visual effect purpose
}
delay(500); // Waits, only for visual effect purpose
}
}
// _______________________________________________________________________________________
void setup(void) // INITIAL SETUP
{
// pinMode(RES, OUTPUT); // Initializes Arduino pin for the Reset line (optional)
// digitalWrite(RES, HIGH); // Sets HIGH the Reset line of the display (optional, can be always high)
delayMicroseconds(200); // Waits 200 us for stabilization purpose
Wire.begin(); // Initiate the Wire library and join the I2C bus as a master
delay(10); // Waits 10 ms for stabilization purpose
if (ROW_N == 2 || ROW_N == 4)
rows = 0x08; // Display mode: 2/4 lines
else
rows = 0x00; // Display mode: 1/3 lines
command(0x22 | rows); // Function set: extended command set (RE=1), lines #
command(0x71); // Function selection A:
data(0x5C); // enable internal Vdd regulator at 5V I/O mode (def. value) (0x00 for disable, 2.8V I/O)
command(0x20 | rows); // Function set: fundamental command set (RE=0) (exit from extended command set), lines #
command(0x08); // Display ON/OFF control: display off, cursor off, blink off (default values)
command(0x22 | rows); // Function set: extended command set (RE=1), lines #
command(0x79); // OLED characterization: OLED command set enabled (SD=1)
command(0xD5); // Set display clock divide ratio/oscillator frequency:
command(0x70); // divide ratio=1, frequency=7 (default values)
command(0x78); // OLED characterization: OLED command set disabled (SD=0) (exit from OLED command set)
if (ROW_N > 2)
command(0x09); // Extended function set (RE=1): 5-dot font, B/W inverting disabled (def. val.), 3/4 lines
else
command(0x08); // Extended function set (RE=1): 5-dot font, B/W inverting disabled (def. val.), 1/2 lines
command(0x06); // Entry Mode set - COM/SEG direction: COM0->COM31, SEG99->SEG0 (BDC=1, BDS=0)
command(0x72); // Function selection B:
data(0x0A); // ROM/CGRAM selection: ROM C, CGROM=250, CGRAM=6 (ROM=10, OPR=10)
command(0x79); // OLED characterization: OLED command set enabled (SD=1)
command(0xDA); // Set SEG pins hardware configuration:
command(0x10); // alternative odd/even SEG pin, disable SEG left/right remap (default values)
command(0xDC); // Function selection C:
command(0x00); // internal VSL, GPIO input disable
command(0x81); // Set contrast control:
command(0x7F); // contrast=127 (default value)
command(0xD9); // Set phase length:
command(0xF1); // phase2=15, phase1=1 (default: 0x78)
command(0xDB); // Set VCOMH deselect level:
command(0x40); // VCOMH deselect level=1 x Vcc (default: 0x20=0,77 x Vcc)
command(0x78); // OLED characterization: OLED command set disabled (SD=0) (exit from OLED command set)
command(0x20 | rows); // Function set: fundamental command set (RE=0) (exit from extended command set), lines #
command(0x01); // Clear display
delay(2); // After a clear display, a minimum pause of 1-2 ms is required
command(0x80); // Set DDRAM address 0x00 in address counter (cursor home) (default value)
command(0x0C); // Display ON/OFF control: display ON, cursor off, blink off
delay(250); // Waits 250 ms for stabilization purpose after display on
if (ROW_N == 2)
new_line[1] = 0xC0; // DDRAM address for each line of the display (only for 2-line mode)
}
// _______________________________________________________________________________________
void loop(void) // MAIN PROGRAM
{
output(); // Execute subroutine "output"
delay(2000); // Waits, only for visual effect purpose
blocks(); // Execute subroutine "blocks"
delay(2000); // Waits, only for visual effect purpose
}