Author Topic: NHD0420CW-Ax3 display with Arduino Uno - Tutorials  (Read 11740 times)

oldmaker

  • Newbie
  • *
  • Posts: 9
  • Karma: 0
    • View Profile
NHD0420CW-Ax3 display with Arduino Uno - Tutorials
« on: March 25, 2015, 06:15:09 PM »
Hi,
I read some posts asking for use of NHD0420CW-Ax3 display family with Arduino Uno.
So I modified the example supplied by Newhaven and adapted it to Arduino Uno, for tutorial purpose. They are fully tested.
I hope these examples may be useful for beginners.

Tutorial 1 - display connected to Arduino Uno via I2C interface:
Code: [Select]
/*
 * Demo_NHD0420CW-Ax3_I2C.ino
 *
 * Tutorial sketch for use of character OLED slim display family by Newhaven with Arduino Uno, using
 * only Wire (I2C) library.  Models: NHD0420CW-Ax3, NHD0220CW-Ax3, NHD0216CW-Ax3. Controller: US2066
 * in this example, the display is connected to Arduino via I2C interface.
 *
 * Displays on the OLED alternately a 4-line message and a sequence of character "block".
 * This sketch assumes the use of a 4x20 display; if different, modify the values of the two variables
 * ROW_N e COLUMN_N.
 * The sketch uses the minimum possible of Arduino's 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:
 * OLED pin 1 (Vss)          to Arduino pin ground
 * OLED pin 2 (VDD)          to Arduino pin 5V
 * OLED pin 3 (REGVDD)       to Arduino pin 5V
 * OLED pin 4 (SA0)          to Vss ground   (to assign I2C address 0x3D, connect to VDD 5V)
 * OLED pin 5 and 6          to Vss ground
 * OLED pin 7 (SCL)          to Arduino pin A5 (SCL); 10K pull-up resistor on OLED pin
 * OLED pin 8 and 9 (SDAin,SDAout) to Arduino pin A4 (SDA); 10K pull-up resistor on OLED pin
 * OLED pin 10 to 15         to Vss ground
 * OLED pin 16 (/RES)        to Arduino pin Reset or VDD 5V (or to Arduino pin D13, to control reset by sw)
 * OLED pin 17 (BS0)         to Vss ground
 * OLED pin 18 (BS1)         to VDD 5V
 * OLED pin 19 (BS2)         to Vss ground
 * 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
 *
 * This example code is in the public domain.
 */

#include <Wire.h>

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
}
« Last Edit: May 19, 2015, 04:35:53 AM by oldmaker »

oldmaker

  • Newbie
  • *
  • Posts: 9
  • Karma: 0
    • View Profile
Re: NHD0420CW-Ax3 display with Arduino Uno - Tutorials
« Reply #1 on: March 25, 2015, 06:17:18 PM »
Tutorial 2 - display connected to Arduino Uno via 8-bit 6800 parallel interface:
Code: [Select]
/*
 * Demo_NHD0420CW-Ax3_parallel_6800_8b.ino
 *
 * Tutorial sketch for use of character OLED slim display family by Newhaven with Arduino Uno, without
 * using any library.  Models: NHD0420CW-Ax3, NHD0220CW-Ax3, NHD0216CW-Ax3. Controller: US2066
 * In this example, the display is connected to Arduino via 8-bit 6800 parallel interface.
 *
 * Displays on the OLED alternately a 4-line message and a sequence of character "block".
 * This sketch assumes the use of a 4x20 display; if different, modify the values of the two variables
 * ROW_N e COLUMN_N.
 * The sketch uses the minimum possible of Arduino's pins; if you intend to use also R/W, /CS or /RES
 * lines, the related instructions are already present, it's sufficient to remove the comment markers.
 *
 * The circuit:
 * OLED pin 1 (Vss)    to Arduino pin ground
 * OLED pin 2 (VDD)    to Arduino pin 5V
 * OLED pin 3 (REGVDD) to Arduino pin 5V
 * OLED pin 4 (D/C)    to Arduino pin D2
 * OLED pin 5 (R/W)    to Vss ground (always write); to enable also read, connect to Arduino pin D13
 * OLED pin 6 (E)      to Arduino pin D3
 * OLED pin 7 (DB0)    to Arduino pin D4
 * OLED pin 8 (DB1)    to Arduino pin D5
 * OLED pin 9 (DB2)    to Arduino pin D6
 * OLED pin 10 (DB3)   to Arduino pin D7
 * OLED pin 11 (DB4)   to Arduino pin D8
 * OLED pin 12 (DB5)   to Arduino pin D9
 * OLED pin 13 (DB6)   to Arduino pin D10
 * OLED pin 14 (DB7)   to Arduino pin D11
 * OLED pin 15 (/CS)   to Vss ground  (or to Arduino pin D12, in case of use of more than one display)
 * OLED pin 16 (/RES)  to Arduino pin Reset or VDD 5V (or to Arduino pin D13, to control reset by sw)
 * OLED pin 17 (BS0)   to Vss ground
 * OLED pin 18 (BS1)   to Vss ground
 * OLED pin 19 (BS2)   to VDD 5V
 * OLED pin 20 (Vss)   to Vss ground
 *
 * Original example created by Newhaven Display International Inc.
 * Modified and adapted to Arduino Uno 16 Mar 2015 by Pasquale D'Antini
 * Modified 19 May 2015 by Pasquale D'Antini
 *
 * This example code is in the public domain.
 */

const byte ROW_N = 4;                 // Number of display rows
const byte COLUMN_N = 20;             // Number of display columns

const byte DC = 2;                    // Arduino's pin assigned to the D/C line
//const byte RW = 13;                 // Arduino's pin assigned to the R/W line (optional, can be always low)
const byte E = 3;                     // Arduino's pin assigned to the E line
//const byte CS = 12;                 // Arduino's pin assigned to the /CS line (optional, can be always low)
//const byte RES = 13;                // Arduino's pin assigned to the Reset line (optional, can be always high)
const byte DATA_PINS[8] = {4, 5, 6, 7, 8, 9, 10, 11};      // Arduino's pins assigned to the data bus

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)
// _______________________________________________________________________________________

void command(byte c)                  // SUBROUTINE: PREPARES THE TRANSMISSION OF A COMMAND
{
   digitalWrite(DC, LOW);             // Sets LOW the D/C line of the display -> command
//   digitalWrite(RW, LOW);           // Sets LOW the R/W line of the display (optional, can be always low)
   send8bit(c);                       // Sends the byte on the data bus
   enableCycle();                     // Calls the enable signal cycle subroutine
}
// _______________________________________________________________________________________

void data(byte d)                     // SUBROUTINE: PREPARES THE TRANSMISSION OF A BYTE OF DATA
{
   digitalWrite(DC, HIGH);            // Sets HIGH the D/C line of the display -> data
//   digitalWrite(RW, LOW);           // Sets LOW the R/W line of the display (optional, can be always low)
   send8bit(d);                       // Sends the byte on the data bus
   enableCycle();                     // Calls the enable signal cycle subroutine
}
// _______________________________________________________________________________________

void enableCycle(void)                // SUBROUTINE: EXECUTE THE ENABLE SIGNAL CYCLE (DATA LATCH)
{
   delayMicroseconds(1);              // Waits 1 us (required for timing purpose)
//   digitalWrite(CS, LOW);           // Sets LOW the /CS line of the display (optional, can be always low)
   digitalWrite(E, HIGH);             // Sets HIGH the E line of the display
   delayMicroseconds(1);              // Waits 1 us (required for timing purpose)
   digitalWrite(E, LOW);              // Sets LOW the E line of the display
//   digitalWrite(CS, HIGH);          // Sets HIGH the /CS line of the display (optional, can be always low)
   delayMicroseconds(1);              // Waits 1 us (required for timing purpose)
}
// _______________________________________________________________________________________

void send8bit(byte value)             // SUBROUTINE: SENDS THE BYTE ON THE DATA BUS
{
   for (byte i = 0; i < 8; i++)                          // One bit at a time,
   {
      digitalWrite(DATA_PINS[i], (value >> i) & 0x01);   //  sets the eight lines of the data bus,
   }                                                     //  to send the character to the display
}
// _______________________________________________________________________________________

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(DC, OUTPUT);               // Initializes Arduino pin for the D/C line
   digitalWrite(DC, LOW);             // Sets LOW the D/C line of the display
//   pinMode(RW, OUTPUT);             // Initializes Arduino pin for the R/W line (optional)
//   digitalWrite(RW, LOW);           // Sets LOW the R/W line of the display (optional, can be always low)
   pinMode(E, OUTPUT);                // Initializes Arduino pin for the E line
   digitalWrite(E, LOW);              // Sets LOW the E line of the display
//   pinMode(CS, OUTPUT);             // Initializes Arduino pin for the /CS line (optional)
//   digitalWrite(CS, HIGH);          // Sets HIGH the /CS line of the display (optional, can be always low)
   for (byte i=0; i<8; i++)
   {
      pinMode(DATA_PINS[i], OUTPUT);     // Initializes all Arduino pins for the data bus
      digitalWrite(DATA_PINS[i], LOW);   // Sets LOW the data bus
   }
//   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
   
   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
}
« Last Edit: May 19, 2015, 04:37:21 AM by oldmaker »

oldmaker

  • Newbie
  • *
  • Posts: 9
  • Karma: 0
    • View Profile
Re: NHD0420CW-Ax3 display with Arduino Uno - Tutorials
« Reply #2 on: March 25, 2015, 06:20:06 PM »
I have an example for 4-bit 6800 parallel interface, too, but it doesn't run as expected.
There is something wrong I don't see or something I don't know.
In attachment there is the image of the output on the display.

UPDATE April 22: thanks to Michael_L, the error has been discovered and the code, fixed, now runs as expected.

Tutorial 3 - display connected to Arduino Uno via 4-bit 6800 parallel interface:
Code: [Select]
/*
 * Demo_NHD0420CW-Ax3_parallel_6800_4b.ino
 *
 * Tutorial sketch for use of character OLED slim display family by Newhaven with Arduino Uno, without
 * using any library.  Models: NHD0420CW-Ax3, NHD0220CW-Ax3, NHD0216CW-Ax3. Controller: US2066
 * In this example, the display is connected to Arduino via 8-bit 6800 parallel interface.
 *
 * Displays on the OLED alternately a 4-line message and a sequence of character "block".
 * This sketch assumes the use of a 4x20 display; if different, modify the values of the two variables
 * ROW_N e COLUMN_N.
 * The sketch uses the minimum possible of Arduino's pins; if you intend to use also R/W, /CS or /RES
 * lines, the related instructions are already present, it's sufficient to remove the comment markers.
 *
 * The circuit:
 * OLED pin 1 (Vss)    to Arduino pin ground
 * OLED pin 2 (VDD)    to Arduino pin 5V
 * OLED pin 3 (REGVDD) to Arduino pin 5V
 * OLED pin 4 (D/C)    to Arduino pin D2
 * OLED pin 5 (R/W)    to Vss ground (always write); to enable also read, connect to Arduino pin D13
 * OLED pin 6 (E)      to Arduino pin D3
 * OLED pin 7 (DB0)    to Vss ground
 * OLED pin 8 (DB1)    to Vss ground
 * OLED pin 9 (DB2)    to Vss ground
 * OLED pin 10 (DB3)   to Vss ground
 * OLED pin 11 (DB4)   to Arduino pin D8
 * OLED pin 12 (DB5)   to Arduino pin D9
 * OLED pin 13 (DB6)   to Arduino pin D10
 * OLED pin 14 (DB7)   to Arduino pin D11
 * OLED pin 15 (/CS)   to Vss ground  (or to Arduino pin D12, in case of use of more than one display)
 * OLED pin 16 (/RES)  to Arduino pin Reset or VDD 5V (or to Arduino pin D13, to control reset by sw)
 * OLED pin 17 (BS0)   to VDD 5V
 * OLED pin 18 (BS1)   to Vss ground
 * OLED pin 19 (BS2)   to VDD 5V
 * OLED pin 20 (Vss)   to Vss ground
 *
 * Original example created by Newhaven Display International Inc.
 * Modified and adapted to Arduino Uno 16 Mar 2015 by Pasquale D'Antini
 * Modified 19 May 2015 by Pasquale D'Antini
 *
 * This example code is in the public domain.
 */

const byte ROW_N = 4;                 // Number of display rows
const byte COLUMN_N = 20;             // Number of display columns

const byte DC = 2;                    // Arduino's pin assigned to the D/C line
//const byte RW = 13;                 // Arduino's pin assigned to the R/W line (optional, can be always low)
const byte E = 3;                     // Arduino's pin assigned to the E line
//const byte CS = 12;                 // Arduino's pin assigned to the /CS line (optional, can be always low)
//const byte RES = 13;                // Arduino's pin assigned to the Reset line (optional, can be always high)
const byte DATA_PINS[4] = {8, 9, 10, 11};                  // Arduino's pins assigned to the data bus

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)
// _______________________________________________________________________________________

void command(byte c)                  // SUBROUTINE: PREPARES THE TRANSMISSION OF A COMMAND
{
   digitalWrite(DC, LOW);             // Sets LOW the D/C line of the display -> command
//   digitalWrite(RW, LOW);           // Sets LOW the R/W line of the display (optional, can be always low)
   send4bit(c >> 4);                  // Sends the higher 4 bits on the data bus
   enableCycle();                     // Calls the enable signal cycle subroutine
   send4bit(c);                       // Sends the lower 4 bits on the data bus
   enableCycle();                     // Calls the enable signal cycle subroutine
}
// _______________________________________________________________________________________

void data(byte d)                     // SUBROUTINE: PREPARES THE TRANSMISSION OF A BYTE OF DATA
{
   digitalWrite(DC, HIGH);            // Sets HIGH the D/C line of the display -> data
//   digitalWrite(RW, LOW);           // Sets LOW the R/W line of the display (optional, can be always low)
   send4bit(d >> 4);                  // Sends the higher 4 bits on the data bus
   enableCycle();                     // Calls the enable signal cycle subroutine
   send4bit(d);                       // Sends the lower 4 bits on the data bus
   enableCycle();                     // Calls the enable signal cycle subroutine
}
// _______________________________________________________________________________________

void enableCycle(void)                // SUBROUTINE: EXECUTE THE ENABLE SIGNAL CYCLE (DATA LATCH)
{
   delayMicroseconds(1);              // Waits 1 us (required for timing purpose)
//   digitalWrite(CS, LOW);           // Sets LOW the /CS line of the display (optional, can be always low)
   digitalWrite(E, HIGH);             // Sets HIGH the E line of the display
   delayMicroseconds(1);              // Waits 1 us (required for timing purpose)
   digitalWrite(E, LOW);              // Sets LOW the E line of the display
//   digitalWrite(CS, HIGH);          // Sets HIGH the /CS line of the display (optional, can be always low)
   delayMicroseconds(1);              // Waits 1 us (required for timing purpose)
}
// _______________________________________________________________________________________

void send4bit(byte value)             // SUBROUTINE: SENDS HALF BYTE ON THE DATA BUS
{
   for (byte i = 0; i < 4; i++)                          // One bit at a time,
   {
      digitalWrite(DATA_PINS[i], (value >> i) & 0x01);   //  sets the four lines of the data bus,
   }                                                     //  to send the half character to the display
}
// _______________________________________________________________________________________

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(4, OUTPUT);
   digitalWrite(4, LOW);
   pinMode(5, OUTPUT);
   digitalWrite(5, LOW);
   pinMode(6, OUTPUT);
   digitalWrite(6, LOW);
   pinMode(7, OUTPUT);
   digitalWrite(7, LOW);
   pinMode(DC, OUTPUT);               // Initializes Arduino pin for the D/C line
   digitalWrite(DC, LOW);             // Sets LOW the D/C line of the display
//   pinMode(RW, OUTPUT);             // Initializes Arduino pin for the R/W line (optional)
//   digitalWrite(RW, LOW);           // Sets LOW the R/W line of the display (optional, can be always low)
   pinMode(E, OUTPUT);                // Initializes Arduino pin for the E line
   digitalWrite(E, LOW);              // Sets LOW the E line of the display
//   pinMode(CS, OUTPUT);             // Initializes Arduino pin for the /CS line (optional)
//   digitalWrite(CS, HIGH);          // Sets HIGH the /CS line of the display (optional, can be always low)
   for (byte i=0; i<4; i++)
   {
      pinMode(DATA_PINS[i], OUTPUT);     // Initializes all Arduino pins for the data bus
      digitalWrite(DATA_PINS[i], LOW);   // Sets LOW the data bus
   }
//   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
   
   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
}
« Last Edit: May 19, 2015, 04:39:08 AM by oldmaker »

oldmaker

  • Newbie
  • *
  • Posts: 9
  • Karma: 0
    • View Profile
Re: NHD0420CW-Ax3 display with Arduino Uno - Tutorials
« Reply #3 on: April 13, 2015, 03:16:14 AM »
Tutorial 4 - display connected to Arduino Uno via SPI interface:
Code: [Select]
/*
 * Demo_NHD0420CW-Ax3_SPI.ino
 *
 * Tutorial sketch for use of character OLED slim display family by Newhaven with Arduino Uno, without
 * using any library.  Models: NHD0420CW-Ax3, NHD0220CW-Ax3, NHD0216CW-Ax3. Controller: US2066
 * in this example, the display is connected to Arduino via SPI interface.
 *
 * Displays on the OLED alternately a 4-line message and a sequence of character "block".
 * This sketch assumes the use of a 4x20 display; if different, modify the values of the two variables
 * ROW_N e COLUMN_N.
 * The sketch uses the minimum possible of Arduino's pins; if you intend to use also /RES or /CS lines,
 * the related instructions are already present, it's sufficient to remove the comment markers.
 *
 * The circuit:
 * OLED pin 1 (Vss)    to Arduino pin ground
 * OLED pin 2 (VDD)    to Arduino pin 5V
 * OLED pin 3 (REGVDD) to Arduino pin 5V
 * OLED pin 4 to 6     to Vss ground
 * OLED pin 7 (SCLK)   to Arduino pin D13 (SCK)
 * OLED pin 8 (SID)    to Arduino pin D11 (MOSI)
 * OLED pin 9 (SOD)    to Arduino pin D12 (MISO) (optional, can be not connected)
 * OLED pin 10 to 14   to Vss ground
 * OLED pin 15 (/CS)   to Vss ground  (or to Arduino pin D2, in case of use of more than one display)
 * OLED pin 16 (/RES)  to Arduino pin Reset or VDD 5V (or to Arduino pin D3, to control reset by sw)
 * OLED pin 17 (BS0)   to Vss ground
 * OLED pin 18 (BS1)   to Vss ground
 * OLED pin 19 (BS2)   to Vss ground
 * OLED pin 20 (Vss)   to Vss ground
 *
 * Original example created by Newhaven Display International Inc.
 * Modified and adapted to Arduino Uno 30 Mar 2015 by Pasquale D'Antini
 * Modified 19 May 2015 by Pasquale D'Antini
 *
 * This example code is in the public domain.
 */

const byte ROW_N = 4;                 // Number of display rows
const byte COLUMN_N = 20;             // Number of display columns

//const byte CS = 2;                  // Arduino's pin assigned to the /CS line (optional, can be always low)
//const byte RES = 3;                 // Arduino's pin assigned to the Reset line (optional, can be always high)
const byte SCLK = 13;                 // Arduino's pin assigned to the SCLK line
const byte SDIN = 11;                 // Arduino's pin assigned to the SID line
//const byte SDOUT = 12;              // Arduino's pin assigned to the SOD line (optional, can be not connected)

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)
// _______________________________________________________________________________________

void command(byte c)                  // SUBROUTINE: PREPARES THE TRANSMISSION OF A COMMAND
{
   byte i = 0;                        // Bit index
   
   for(i=0; i<5; i++)
   {
      digitalWrite(SDIN, HIGH);
      clockCycle();
   }
   for(i=0; i<3; i++)
   {
      digitalWrite(SDIN, LOW);
      clockCycle();
   }
   
   send_byte(c);                      // Transmits the byte
}
// _______________________________________________________________________________________

void data(byte d)                     // SUBROUTINE: PREPARES THE TRANSMISSION OF A BYTE OF DATA
{
   byte i = 0;                        // Bit index
   
   for(i=0; i<5; i++)
   {
      digitalWrite(SDIN, HIGH);
      clockCycle();
   }
   digitalWrite(SDIN, LOW);
   clockCycle();
   digitalWrite(SDIN, HIGH);
   clockCycle();
   digitalWrite(SDIN, LOW);
   clockCycle();
   
   send_byte(d);                      // Transmits the byte
}
// _______________________________________________________________________________________

void send_byte(byte tx_b)             // SUBROUTINE: SEND TO THE DISPLAY THE BYTE IN tx_b
{
   byte i = 0;                        // Bit index
   
   for(i=0; i<4; i++)
   {
      if((tx_b & 0x01) == 1)
      {
         digitalWrite(SDIN, HIGH);
      }
      else
      {
         digitalWrite(SDIN, LOW);
      }
      clockCycle();
      tx_b = tx_b >> 1;
   }
   
   for(i=0; i<4; i++)
   {
      digitalWrite(SDIN, LOW);
      clockCycle();
   }
   
   for(i=0; i<4; i++)
   {
      if((tx_b & 0x1) == 0x1)             // <------- Change
      {
         digitalWrite(SDIN, HIGH);
      }
      else
      {
         digitalWrite(SDIN, LOW);
      }
      clockCycle();
      tx_b = tx_b >> 1;
   }
   
   for(i=0; i<4; i++)
   {
      digitalWrite(SDIN, LOW);
      clockCycle();
   }
}
// _______________________________________________________________________________________

void clockCycle(void)                 // SUBROUTINE: EXECUTE THE CLOCK SIGNAL CYCLE
{
//   digitalWrite(CS, LOW);           // Sets LOW the /CS line of the display (optional, can be always low)
//   delayMicroseconds(1);            // Waits 1 us (required for timing purpose)
   digitalWrite(SCLK, LOW);           // Sets LOW the SCLK line of the display
   delayMicroseconds(1);              // Waits 1 us (required for timing purpose)
   digitalWrite(SCLK, HIGH);          // Sets HIGH the SCLK line of the display
   delayMicroseconds(1);              // Waits 1 us (required for timing purpose)
//   delayMicroseconds(1);            // Waits 1 us (required for timing purpose)
//   digitalWrite(CS, HIGH);          // Sets HIGH the /CS line of the display (optional, can be always low)
}
// _______________________________________________________________________________________

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(SCLK, OUTPUT);             // Initializes Arduino pin for the SCLK line
   digitalWrite(SCLK, HIGH);          // Sets HIGH the SCLK line of the display
   pinMode(SDIN, OUTPUT);             // Initializes Arduino pin for the SDIN line
   digitalWrite(SDIN, LOW);           // Sets LOW the SDIN line of the display
//   pinMode(SDOUT, INPUT);           // Initializes Arduino pin for the SDOUT line (optional, can be not connected)
//   pinMode(CS, OUTPUT);             // Initializes Arduino pin for the /CS line (optional)
//   digitalWrite(CS, HIGH);          // Sets HIGH the /CS line of the display (optional, can be always low)
//   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
   
   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
}
« Last Edit: May 19, 2015, 04:40:59 AM by oldmaker »

Michael_L

  • Administrator
  • Hero Member
  • *****
  • Posts: 356
  • Karma: 33
    • View Profile
Re: NHD0420CW-Ax3 display with Arduino Uno - Tutorials
« Reply #4 on: April 22, 2015, 11:48:41 AM »
Thanks for sharing your code!  As for your question in your 3rd tutorial, try changing the value after command DA is sent to 0x10 instead of 0x00.  ;)

oldmaker

  • Newbie
  • *
  • Posts: 9
  • Karma: 0
    • View Profile
Re: NHD0420CW-Ax3 display with Arduino Uno - Tutorials
« Reply #5 on: April 22, 2015, 04:00:10 PM »
Thank you very much, Michael.
I did so many tests and attempts that I didn't see I had swapped two lines  ;D
Code fixed and post updated.
Thanks again.
« Last Edit: April 22, 2015, 04:09:02 PM by oldmaker »

macsboost

  • Newbie
  • *
  • Posts: 2
  • Karma: 0
    • View Profile
Re: NHD0420CW-Ax3 display with Arduino Uno - Tutorials
« Reply #6 on: May 04, 2015, 09:11:18 PM »
can you share your display pinout.
I have yet to get my display to work.

I have another i2c display working from the same tutorial from another mfg, so something must be right.

oldmaker

  • Newbie
  • *
  • Posts: 9
  • Karma: 0
    • View Profile
Re: NHD0420CW-Ax3 display with Arduino Uno - Tutorials
« Reply #7 on: May 06, 2015, 01:41:43 PM »
The complete pinout is reported in the comment text at the beginning of each tutorial.
The examples are all tested with two Newhaven display.

macsboost

  • Newbie
  • *
  • Posts: 2
  • Karma: 0
    • View Profile
Re: NHD0420CW-Ax3 display with Arduino Uno - Tutorials
« Reply #8 on: May 07, 2015, 11:42:10 PM »
thanks!  too many sleepless nights!

Rage441

  • Newbie
  • *
  • Posts: 2
  • Karma: 0
    • View Profile
Re: NHD0420CW-Ax3 display with Arduino Uno - Tutorials
« Reply #9 on: October 19, 2015, 11:44:06 PM »
Thanks for the great work on this.  Just got it running tonight.  I'm trying to change the brightness of the display, tried changing the contrast value, (0x7F is the default) but it doesn't seem to have any effect; am I missing something else?

Paul_B

  • Administrator
  • Sr. Member
  • *****
  • Posts: 248
  • Karma: 16
    • View Profile
Re: NHD0420CW-Ax3 display with Arduino Uno - Tutorials
« Reply #10 on: October 20, 2015, 07:44:56 AM »
Please try this code, let me know if the contrast changes.

https://github.com/NewhavenDisplay/NHD_US2066

Code: [Select]
//---------------------------------------------------------
/*

NHD_0216AW_XB3.ino

Program for writing to Newhaven Display Slim OLEDs based on US2066 controller.

Pick one up today in the Newhaven Display shop!
------> http://www.newhavendisplay.com/oled-slim-character-oleds-c-119_825.html

This code is written for the Arduino Mega.

Copyright (c) 2015 - Newhaven Display International, LLC.

Newhaven Display invests time and resources providing this open source code,
please support Newhaven Display by purchasing products from Newhaven Display!

*/
//---------------------------------------------------------

#include <SPI.h>
#include <Arduino.h>
#include <Wire.h>
#include <avr\io.h>

#include "NHD_US2066.h"
unsigned char text1[] = {" Please Support "};
unsigned char text2[] = {"  Open-Source   "};
unsigned char text3[] = {"   Hardware &   "};
unsigned char text4[] = {"   Software !!  "};

unsigned char text5[] = {"Newhaven Display"};
unsigned char text6[] = {" 2X16 Character "};
unsigned char text7[] = {"  Slim  Design  "};
unsigned char text8[] = {"----------------"};



void output()
{
                int i;

        command(0x01);
        delay(2);
        for(i=0;i<16;i++){
          data(text1[i]);
        }
       
        command(0xA0);
        for(i=0;i<16;i++){
          data(text2[i]);
        }

        delay(2000);

        command(0x01);
        delay(2);
        for (i=0;i<16;i++){
                                data(text3[i]);
        }
               
        command(0xA0);
        for (i=0;i<16;i++){
                                data(text4[i]);
        }

        delay(3500);
       
        command(0x01);
        delay(2);
        for(i=0;i<16;i++){
          data(text5[i]);
        }
       
        command(0xA0);
        for(i=0;i<16;i++){
          data(text6[i]);
        }

        delay(2000);

        command(0x01);
        delay(2);
        for (i=0;i<16;i++){
                                data(text7[i]);
        }
               
        command(0xA0);
        for (i=0;i<16;i++){
                                data(text8[i]);
        }

}

void blocks()
{
                int i;

        command(0x01);
        delay(2);

        for(i=0;i<16;i++){
          data(0x1F);
        }

        command(0xA0);
        for(i=0;i<16;i++){
          data(0x1F);
        }
}

void setup()
{
init_oled();
}

void loop()

  while(1)
  {
    //output();
   
    blocks();
    command(0x78);
    command(0x2A);
    command(0x79);
   
    command(0x81);  //set contrast control
    command(0x01);  //set contrast control
   
    delay(2000);
   
    command(0x81);  //set contrast control
    command(0xFF);  //set contrast control
   
    delay(2000); 
  }
}

« Last Edit: December 06, 2016, 02:19:13 PM by Michael_L »

Paul_B

  • Administrator
  • Sr. Member
  • *****
  • Posts: 248
  • Karma: 16
    • View Profile
Re: NHD0420CW-Ax3 display with Arduino Uno - Tutorials
« Reply #11 on: October 20, 2015, 07:46:58 AM »
In order for you to send the “Set Contrast Control”  command RE and SD must be set to 1, please see the attachment.

E.g. The following commands set RE – SD  to the appropriate values before setting the contrast.

command(0x78);
command(0x2A);
command(0x79);             

I recommend you review the US2066 datasheet, this will give you a better understanding on how to send commands.

http://www.newhavendisplay.com/app_notes/US2066.pdf

Hope this helps  ;)

Rage441

  • Newbie
  • *
  • Posts: 2
  • Karma: 0
    • View Profile
Re: NHD0420CW-Ax3 display with Arduino Uno - Tutorials
« Reply #12 on: November 05, 2015, 09:44:21 PM »
Appreciate the help on this one, but still having issues.  I'm running the code in tutorial 1, I2C interface, 5v, Arduino Uno.   Tried changing the contrast value in the code and it has no effect.  Tried adding the code above and that has no effect either.  Sometimes the display dims a little, but it's not consistent.  I should be able to dim this right down to almost nothing.  The most change in brightness I've seen is maybe from 100% to 80%.  Was troubleshooting again tonight and now the display won't turn on.  Ran an I2C Scanner sketch and can see the I2C address of 3C for the display, So it's communicating.  Rechecked all input pins and they getting power and ground in the right places.  Tried reloading Tutorial 1 sketch to no effect.  Anyone have any ideas?

Saurabh_B

  • Administrator
  • Hero Member
  • *****
  • Posts: 355
  • Karma: 10
    • View Profile
Re: NHD0420CW-Ax3 display with Arduino Uno - Tutorials
« Reply #13 on: November 06, 2015, 08:35:50 AM »
Hi,

Would you be able to post the code snipped of how you are adjusting the contrast?

Morne

  • Newbie
  • *
  • Posts: 1
  • Karma: 2
    • View Profile
Re: NHD0420CW-Ax3 display with Arduino Uno - Tutorials
« Reply #14 on: April 01, 2016, 04:15:45 PM »
Hello all!

First of all I want to send out huge thanks to Pasquale for providing these examples, they made it very easy for me to get started with the 20x4 character OLED. However I noticed that the SPI example used bit banged software SPI, which is rather slow and filling the screen with characters take about 40 ms.

Not completely statsfiende by this I decided change the implementation to use HW SPI. And after a few hours of struggling I finally got it working! It is also super fast. Filling the screen now takes slightly less than 1 ms, which is even faster then using the 4 bit 6800 interface (11 ms to fil the screen).

So, without more ado, here is the code for a HW SPI implementation.

Code: [Select]
/*
 * Demo_NHD0420CW-Ax3_SPI_HW.ino
 *
 * Tutorial sketch for use of character OLED slim display family by Newhaven with Arduino Uno, without
 * using any library.  Models: NHD0420CW-Ax3, NHD0220CW-Ax3, NHD0216CW-Ax3. Controller: US2066
 * in this example, the display is connected to Arduino via SPI interface.
 *
 * Displays on the OLED alternately a 4-line message and a sequence of character "block".
 * This sketch assumes the use of a 4x20 display; if different, modify the values of the two variables
 * ROW_N e COLUMN_N.
 * The sketch uses the minimum possible of Arduino's pins; if you intend to use also /RES or /CS lines,
 * the related instructions are already present, it's sufficient to remove the comment markers.
 *
 * The circuit:
 * OLED pin 1 (Vss)    to Arduino pin ground
 * OLED pin 2 (VDD)    to Arduino pin 5V
 * OLED pin 3 (REGVDD) to Arduino pin 5V
 * OLED pin 4 to 6     to Vss ground
 * OLED pin 7 (SCLK)   to Arduino pin D13 (SCK)
 * OLED pin 8 (SID)    to Arduino pin D11 (MOSI)
 * OLED pin 9 (SOD)    to Arduino pin D12 (MISO) (optional, can be not connected)
 * OLED pin 10 to 14   to Vss ground
 * OLED pin 15 (/CS)   to Vss ground  (or to Arduino pin D2, in case of use of more than one display)
 * OLED pin 16 (/RES)  to Arduino pin Reset or VDD 5V (or to Arduino pin D3, to control reset by sw)
 * OLED pin 17 (BS0)   to Vss ground
 * OLED pin 18 (BS1)   to Vss ground
 * OLED pin 19 (BS2)   to Vss ground
 * OLED pin 20 (Vss)   to Vss ground
 *
 * Original example created by Newhaven Display International Inc.
 * Modified and adapted to Arduino Uno 30 Mar 2015 by Pasquale D'Antini
 * Modified 19 May 2015 by Pasquale D'Antini
 * Modified to use hardware SPI 1 April 2016 by Joakim Sandström
 *
 * This example code is in the public domain.
 */

// inslude the SPI library:
#include <SPI.h>


const byte ROW_N = 4;                 // Number of display rows
const byte COLUMN_N = 20;             // Number of display columns

//const byte RES = 3;                 // Arduino's pin assigned to the Reset line (optional, can be always 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)
// _______________________________________________________________________________________
void command(byte c)                  // SUBROUTINE: PREPARES THE TRANSMISSION OF A COMMAND
{
  SPI.transfer(0x1F);

  send_byte(c);                      // Transmits the byte
}


// _______________________________________________________________________________________
void data(byte d)
{
  SPI.transfer(0x5F);

  send_byte(d);
}

// _______________________________________________________________________________________
void send_byte(byte tx_b)
{
  //Split the bytes into two and pad the last four bits with 0s
  byte tx_b1 = tx_b & 0x0F;
  byte tx_b2 = (tx_b >> 4) & 0x0F;

  //Or together the bytes
  int tx_int = (tx_b2<<8)|tx_b1;

  //transfer it
  SPI.transfer16(tx_int);
}

// _______________________________________________________________________________________

void output(void)                     // SUBROUTINE: DISPLAYS THE FOUR STRINGS, THEN THE SAME IN REVERSE ORDER
{
  unsigned long lastTime = 0;
  unsigned long temp;
  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

  lastTime = millis();
  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)
    }
  }
  temp = millis() - lastTime;
  Serial.println(temp);
}
// _______________________________________________________________________________________

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)
  SPI.begin();
  SPI.setBitOrder(LSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV2);
  SPI.setDataMode(SPI_MODE3);

  delayMicroseconds(200);            // Waits 200 us 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)
  Serial.begin(115200); //For performance measurement
}
// _______________________________________________________________________________________

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
}
« Last Edit: April 01, 2016, 04:21:34 PM by Morne »

 

Blank Display on NHD‐C0220BiZ‐FS(RGB)‐FBW‐3VM

Started by SteveCBoard Character LCDs

Replies: 3
Views: 4564
Last post May 13, 2014, 12:04:36 AM
by SteveC
NHD‐C12864A1Z‐FSW‐FBW‐HTT display clears after draw

Started by EdAverillBoard Graphic LCDs

Replies: 6
Views: 5698
Last post November 07, 2014, 08:25:20 AM
by Michael_L
NHD‐4.3‐480272EF‐ATXL#‐CTP | FAN5333 | BBB | Nothing on the Display

Started by Alias_AliasBoard TFTs

Replies: 2
Views: 3406
Last post Today at 08:40:38 PM
by tolikkk
NHD-0420DZW-AG5 - Display "sometimes" shows only 2 lines

Started by stylonurusBoard OLEDs

Replies: 5
Views: 5574
Last post June 18, 2014, 10:09:49 AM
by Michael_L
NHD-C0220BiZ Sometimes Ignoring "Clear Display" Command

Started by dstoverBoard Character LCDs

Replies: 2
Views: 3749
Last post March 27, 2014, 05:41:27 PM
by Michael_L