/*****************************************************************************
* Program for writing to Newhaven Display NHD-0240AZ Series with ST7066U controller.
* This code is written for the Arduino Uno (ATmega328P) in 6800 Mode 8-Bit or 4-Bit
* Parallel Interface.
*
* Newhaven Display invests time and resources providing this open source code,
* Please support Newhaven Display by purchasing products from Newhaven Display!
*
* Copyright 2024, Newhaven Display International, Inc.
*
* This code is provided as an example only and without any warranty by Newhaven Display.
* Newhaven Display accepts no responsibility for any issues resulting from its use.
* The developer of the final application incorporating any parts of this
* sample code is responsible for ensuring its safe and correct operation
* and for any consequences resulting from its use.
* See the GNU General Public License for more details.
*****************************************************************************/
/****************************************************
* PINOUT: Arduino Uno -> Character OLED *
UNO LCD
--------------------------
GND 1 (VSS)
5V 2 (VDD)
* 3 (V0)
13 4 (RS)
12 5 (R/W)
11 6 (E)
0 7 (DB0)
1 8 (DB1)
2 9 (DB2)
3 10 (DB3)
4 11 (DB4)
5 12 (DB5)
6 13 (DB6)
7 14 (DB7)
5V 15 (LED+)
GROUND 16 (LED-)
*Contrast potentiometer: refer to specification forwiring diagram
*****************************************************************************/
#define RS 8
#define RW 9
#define EN 10
// Interface Select:
// 0 = 8-bit parallel
// 1 = 4-bit parallel
const unsigned char interface = 0;
/****************************************************
* Text Strings *
****************************************************/
char const text1[] = "Newhaven 02x40 Character ";
char const text2[] = "Display LCD ";
char const text3[] = "02x40 Character Newhaven ";
char const text4[] = "8-Bit LCD Display ";
char const text5[] = "4-Bit LCD Display ";
char const text6[] = "LCD Display ";
/****************************************************
* Display Write Functions *
****************************************************/
void command(char c){ // Write 8-Bit / 4-Bit Command to display.
PORTD = c; // Set data on parallel bus.
switch(interface){ // 8-Bit / 4-Bit Interface Select
case 0:
digitalWrite(RS, LOW); // Register Select: Command
digitalWrite(RW, LOW); // Read/Write Select: Write
digitalWrite(EN, HIGH); // Toggle enable signal to latch data.
delay(1);
digitalWrite(EN,LOW);
break;
case 1:
digitalWrite(RS, LOW); // Register Select: Command
digitalWrite(RW, LOW); // Read/Write Select: Write
digitalWrite(EN, HIGH); // Toggle enable signal to latch data.
delay(1);
digitalWrite(EN,LOW);
c = c << 4; // Shift left lower 4 bits of data byte.
PORTD = c; // Set parallel bus to new data byte.
digitalWrite(EN, HIGH); // Toggle enable signal to latch data.
delay(1);
digitalWrite(EN,LOW);
break;
default:
break;
delay(1);
}
}
void data(char d){ // Write 8-Bit / 4-Bit Data to display.
PORTD = d;
switch(interface){ // 8-Bit / 4-Bit Interface Select
case 0:
digitalWrite(RS, HIGH); // Register Select: Data
digitalWrite(RW, LOW); // Read/Write Select: Write
digitalWrite(EN, HIGH); // Toggle enable signal to latch data.
delay(1);
digitalWrite(EN,LOW);
break;
case 1:
digitalWrite(RS, HIGH); // Register Select: Data
digitalWrite(RW, LOW); // Read/Write Select: Write
digitalWrite(EN, HIGH); // Toggle enable signal to latch data.
delay(1);
digitalWrite(EN,LOW);
d = d << 4; // Shift left lower 4 bits of data byte.
PORTD = d; // Set parallel bus to new data byte.
digitalWrite(EN, HIGH); // Toggle enable signal to latch data.
delay(1);
digitalWrite(EN,LOW);
break;
default:
break;
delay(1);
}
}
/****************************************************
* Display Commands *
****************************************************/
void Clear(){ // Clear the display.
command(0x01);
delay(2);
}
void returnHome(){ // Return the cursor to the home position.
command(0x02);
delay(1);
}
void nextLine(){ // Set address to 1st character of second line
command(0xC0);
delay(1);
}
void wake(char i){ // Writes Wake command to display for specified delay.
command(0x30);
delay(i);
}
/****************************************************
* Display Functions *
****************************************************/
void display1(){
returnHome(); // Set address to 1st character of Row 1
Clear();
delay(100);
for(int i=0; i<40; i++){ // Write 40 Characters to Row 1 from text string 1
data(text1[i]);
delay(25);
}
nextLine(); // Set address to 1st character of Row 2
for(int i=0; i<40;i++){ // Write 40 Characters to Row 1 from text string 2
data(text2[i]);
delay(25);
}
returnHome();
delay(250);
}
void display2(){
returnHome(); // Set address to 1st character of Row 1
Clear();
for(int i=0; i<40; i++){ // Write 40 Characters to Row 1 from text string 3
data(text3[i]);
delay(25);
}
nextLine(); // Set address to 1st character of Row 2
if (interface == 0){ // Select text string for 8-Bit interface
for(int i=0; i<40;i++){ // Write 40 Characters to Row 1 from text string 4
data(text4[i]);
delay(25);
}
} else if(interface == 1){ // Select text string for 4-Bit interface
for(int i=0; i<40;i++){ // Write 40 Characters to Row 1 from text string 5
data(text5[i]);
delay(25);
}
} else{
for(int i=0; i<40;i++){ // Select default text string
data(text6[i]); // Write 40 Characters to Row 1 from text string 6
delay(25);
}
}
returnHome();
delay(250);
}
/****************************************************
* Display Setup *
****************************************************/
void init_8Bit(){ // Initialization Sequence for 8-Bit Interface
command(0x38); // 8-Bit / 2-Line
command(0x0D); // Display ON; Cursor OFF; Blinking ON;
command(0x06); // Entry Mode set
}
void init_4Bit(){ // Initialization Sequence for 4-Bit Interface
Set_4Bit(0x20); // Function Set command for display initialization.
command(0x28); // Function Set command with setting: 4-Bit / 2 Line
command(0x0D); // Display ON; Cursor OFF; Blinking ON;
command(0x06); // Entry Mode set
}
void Set_4Bit(char i){ // Write 0x30 to parallel bus for 4-Bit Initialization Setting.
PORTD = i;
digitalWrite(RS, LOW); // Register Select: Command
digitalWrite(RW, LOW); // Read/Write Select: Write
digitalWrite(EN, HIGH); // Toggle enable signal to latch data.
delay(1);
digitalWrite(EN,LOW);
delay(1);
}
void setup(){ // Run Once for Program setup and initalization
DDRD = 0xFF; // sets all Pins in Port D as High
DDRB = 0x07; // sets lower 3 pins in Port B as High
digitalWrite(EN, LOW);
delay(300); // Wait time > 40ms for power stablization after Vcc > 4.5V
wake(30); // command 0x30 = Wake up; Must wait 5ms, busy flag not available
wake(10); // command 0x30 = Wake up #2; Must wait 160us, busy flag not available
wake(10); // command 0x30 = Wake up #3; Must wait 160us, busy flag not available
switch (interface){ // 8-Bit / 4-Bit interface Selection
case 0:
init_8Bit();
delay(100);
break;
case 1:
init_4Bit();
delay(100);
break;
default:
break;
}
}
void loop(){
display1();
delay(1500);
Clear();
delay(250);
display2();
delay(1500);
Clear();
delay(500);
}