/*****************************************************************************
/ Program for writing to Newhaven Display's 128x64 Graphic COG with the ST7565R Controller.
/ This code is written for the Arduino Uno R3 using Parallel Interface.
/ Logic level shifters are required to convert the Arduino 5V logic to 3.3V logic.
/
/ Newhaven Display invests time and resources providing this open source code,
/ Please support Newhaven Display by purchasing products from Newhaven Display!
* Copyright (c) 2025, Newhaven Display International
*
* 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 -> LCD *
****************************************************/
#define CS 8 //Active Low Chip Select
#define RST 9 //Active Low Reset Signal
#define RS 10 //Register Select 0 = command. 1 = data.
#define RW 11 //Read = 1; Write = 0;
#define EN 12 //Active High Enable Signal
// Parallel/Serial Select: Parallel
// Display Pin PS connected to 3.3V
// Interface Select: 6800
// Display Pin C86 connected to 3.3V
/****************************************************
* Custom Characters *
*****************************************************/
unsigned char NHD_Logo[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x80, 0xC0, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x7C, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x00, 0xF8, 0xF8, 0xF0, 0x00, 0x00, 0xF8, 0xF8, 0x00, 0x00, 0x00,
0x00, 0xC0, 0xF0, 0x78, 0x78, 0x78, 0x78, 0x78, 0x00, 0x00, 0x00, 0xF8, 0xF0, 0x00, 0x00, 0x00,
0xF8, 0xF8, 0xC0, 0x00, 0x00, 0xC0, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0xF8, 0xF8, 0x00, 0x00, 0x00,
0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF8, 0xF8, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
0xF8, 0xF8, 0xC0, 0x00, 0x00, 0x00, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0x80, 0xF0, 0xF0, 0x78, 0x78,
0x78, 0x78, 0x00, 0x00, 0x00, 0xF8, 0xF8, 0xF8, 0xC0, 0x00, 0x00, 0xF8, 0xF8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x07, 0x0B, 0x1F, 0x1F, 0x17, 0x0B, 0x01, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF0, 0xF0,
0xF0, 0xF0, 0xF0, 0xF0, 0xE0, 0x00, 0xFF, 0x01, 0x07, 0xF8, 0xC0, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0x00, 0xFF, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0xFF,
0x7F, 0x03, 0xFF, 0xE0, 0x00, 0xFF, 0x3F, 0x03, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x78, 0x70, 0x78,
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xBF, 0x8F, 0x81, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00,
0x0F, 0x3F, 0xFF, 0x00, 0xE0, 0xF8, 0x0F, 0x01, 0x00, 0x00, 0xF8, 0xFF, 0x79, 0x78, 0x70, 0x70,
0x70, 0x70, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x1F, 0xF0, 0xE0, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xF8, 0xFE, 0xFF, 0xFF, 0xF8, 0xD0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xB8, 0x3C, 0x07, 0x03, 0x80, 0xF0, 0xF0, 0xF0,
0xF0, 0xF0, 0xF0, 0xF0, 0xE0, 0x00, 0xFF, 0x00, 0x00, 0x03, 0x3F, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x1F, 0x78, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x7F,
0x00, 0x00, 0x1F, 0xFF, 0xFE, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0xFF, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x07, 0x07, 0x07, 0x07, 0x3F, 0xFF, 0x80, 0x00, 0x00,
0x00, 0x00, 0x01, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0F, 0x7C, 0x78, 0xF0, 0xF0,
0xF0, 0xF0, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x07, 0x1F, 0xFF, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x3F, 0xFF, 0xFF, 0xFF, 0x7F, 0x1B,
0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x03, 0x00, 0x00, 0xE0, 0x7C, 0x0F, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0, 0xE0, 0xE0, 0x80, 0x00, 0x00, 0x00,
0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x00, 0x00,
0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00,
0xF0, 0xF0, 0xF0, 0x00, 0x00, 0x80, 0xF0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xE0, 0xF4, 0xFE, 0xFF, 0xFE, 0xFC, 0x80, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xF0, 0x2E, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0x00, 0x00, 0x00,
0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x7F, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0x00, 0x00,
0x00, 0x00, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x07, 0x3F, 0xFE, 0xE0, 0x00, 0x00, 0x00,
0x00, 0x03, 0x07, 0xF8, 0xFE, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0F, 0x7F, 0xFF, 0xFF, 0xFF, 0x3F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x0F, 0x0F, 0x0F, 0x0F, 0x0B, 0x0F, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE0, 0xE0, 0xE0, 0xE0, 0xFC, 0x3F, 0x00, 0x00, 0x00,
0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE1, 0xF1, 0xFF, 0x00, 0x00,
0x00, 0x00, 0xFF, 0xFF, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE0,
0xE0, 0xE0, 0xE0, 0x00, 0x00, 0x80, 0xF8, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0xFF, 0xE0, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
/****************************************************
* Function Commands *
*****************************************************/
void command(unsigned char c){
PORTD = c;
digitalWrite(RS, LOW); // Set Command Write
digitalWrite(RW, LOW); // Write Start
digitalWrite(CS, LOW);
digitalWrite(EN, HIGH); // Latch
digitalWrite(EN, LOW);
digitalWrite(CS, HIGH); // End Write
digitalWrite(RW, HIGH);
}
void data(unsigned char d){
PORTD = d;
digitalWrite(RS, HIGH); // Set Data Write
digitalWrite(RW, LOW); // Write Start
digitalWrite(CS, LOW);
digitalWrite(EN, HIGH); // Latch
digitalWrite(EN, LOW);
digitalWrite(CS, HIGH); // End Write
digitalWrite(RW, HIGH);
}
/****************************************************
* Display Commands *
*****************************************************/
void Display_ON(){
command(0xAF);
delay(300);
}
void Display_OFF(){
command(0xAE);
delay(1);
}
void Set_StartLine(){ //This instruction sets the line address of the Display Data RAM to determine the initial display line.
command(0x40); //Display Start Line (COM0->COM63): Line Address 0
}
void Set_PageAddr(unsigned char Y){ //Y [3:0] defines the Y address vector address of the display RAM.
command(Y);
}
void Set_ColumnAddr(unsigned char X){ //This instruction is used to define area of DDRAM where MCU can access.
command(X);
}
void SEG_Dir(){ //Set scan direction of SEG
command(0xA0); //Normal direction (SEG0->SEG131): 0xA0 | Reverse direction (SEG131->SEG0): 0xA1
}
void COM_Dir(){ //Set output direction of COM
command(0xC8); //Normal direction (COM0->COM63): 0xC0 | Reverse direction (COM63->COM0): 0xC8
}
void Inv_Disp(){ //This instruction changes the selected and non-selected voltage of SEG.
command(0xA6); //Normal display (white -> Black): 0xA6 | Inverse display (Black -> White): 0xA7
}
void Set_Pixel(unsigned char P){ //This instruction will let all segments output the selected voltage and make all pixels turned ON.
command(P); //Normal display: 0xA4 | Inverse display: 0xA5
}
void Bias_Sel(){ //LCD drive voltage bias (V0-V4) ratio.
command(0xA2); //Duty: 1/65, Bias: 1/9
}
void PwrCtl(){ //This instruction controls the built-in power circuits. Typically, these 3 flags are turned ON at the same time.
command(0x2F); //Built-in Power Control: Booster-ON, Regulator-ON, Follower-ON
}
void Ratio_Res(unsigned char R){ //This instruction controls the regulation ratio of the built-in regulator.
command(R); //Regulation Ratio set to 5.5
}
void Set_EVol(unsigned char V){ //Set Electronic Volume level
command(0x81); //(Double Byte: 1 of 2) EV Command: Optimal Voltage 8.8V.
command(V); //(Double Byte: 2 of 2) EV Value: Adjust value with Regulation Ratio for Optimal Contrast.
}
void PwrSave(){ //This instruction used to set mode of power save only.
command(0xAC); //Set Sleep Mode
}
/****************************************************
* Display Function *
*****************************************************/
void Disp(unsigned char *lcd_string){
unsigned int i,j;
unsigned char page = 0xB0;
Display_OFF(); //Display OFF
Set_StartLine(); //Display start address + 0x40
for(i=0;i<8;i++){ //64pixel display / 8 pixels per page = 8 pages
command(page); //send page address
command(0x10); //column address upper 4 bits + 0x10
command(0x00); //column address lower 4 bits + 0x00
for(j=0;j<128;j++){ //128 columns wide
data(*lcd_string); //send picture data
lcd_string++;
}
page++; //after 128 columns, go to next page
}
Display_ON();
}
/****************************************************
* Set-up Functions *
*****************************************************/
void initLCD(){ //Display initalization sequence
SEG_Dir();
Display_OFF();
COM_Dir();
Bias_Sel();
PwrCtl();
Ratio_Res(0x25); //Regulation Ratio set to 5.5
Set_EVol(0x18); //18
Display_ON();
}
void setup() {
DDRB = 0xFF; //Enable digital pins 8 - 13 as output for RS,RW,EN,CS,and RES
DDRD = 0xFF; //Enable digital pins 1 - 7 as output for D0-D7
digitalWrite(RST, LOW);
delay(100);
digitalWrite(RST, HIGH);
delay(100);
digitalWrite(CS, HIGH);
digitalWrite(EN, HIGH);
digitalWrite(RW, HIGH);
digitalWrite(RS, HIGH);
delay(100);
initLCD();
delay(100);
Disp(NHD_Logo);
delay(1500);
Set_Pixel(0xA5); // All Pixel On
delay(1500);
}
void loop() {
Set_Pixel(0xA5); // All Pixel On
delay(1500);
Set_Pixel(0xA4); //Normal Display
delay(1500);
}