//---------------------------------------------------------
/*
Program for writing to Newhaven Display NHD-1.69-160128B with SSD1333 controller.
This code is written for the Arduino Due.
This code will initialize the display and fill the screen with different colors
Copyright (c) 2024 - Newhaven Display International, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
*/
//---------------------------------------------
/*---------------Pinout Table--------------
NHD-1.69-160128B Arduino Due
1 NC
2 GND
3
4
5
6 D35
7 D34
8 D33
9 D32
10 D31
11 D30
12 D29
13 D28
14 D27
15 D26
16 D38
17 D39
18 D37
19 D25
20 D36
21 NC
22 3.3V
23 GND
24
25
26
27
28
29 GND
30 NC
----------------------------------------------*/
//--------------Interface Selection---------------------------------------------------------------------
const unsigned char interface = 0; //0 = Parallel 6800 1 = Parallel 8080 2 = 4-Wire SPI 3 = I2C
//------------------------------------------------------------------------------------------------------
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Pin Definition
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
#define DC 25 //DC
#define RW 26 //RW / WR
#define E 27 //E / RD
#define DB0 28 //DB0
#define DB1 29 //DB1
#define DB2 30 //DB2
#define DB3 31 //DB3
#define DB4 32 //DB4
#define DB5 33 //DB5
#define DB6 34 //DB6
#define DB7 35 //DB7
#define RES 36 //RES
#define CS 37 //CS
#define BS1 38 //BS1
#define BS2 39 //BS2
#define WHITE 0xFF, 0xFF
#define RED 0xF8, 0x00
#define ORANGE 0xFD, 0x00
#define YELLOW 0xFF, 0xE0
#define GREEN 0x07, 0xE0
#define BLUE 0x00, 0x1F
#define VIOLET 0xC8, 0x13
#define BLACK 0x00, 0x00
unsigned char tx_packet[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
const char slave2w = 0x78;
void write_8bit(unsigned char c){
for(int i =35;i>=28;i--){
if( (c&0x80) ==0x80){
digitalWrite(i,HIGH);
}
else {
digitalWrite(i,LOW);
}
c= c<<1;
}
}
void command(unsigned char c) // send command to OLED
{
unsigned char i;
unsigned char mask = 0x80;
switch(interface)
{
case 0: digitalWrite(DC, LOW); // D/C set to LOW for comm_out_2
delayMicroseconds(1);
write_8bit(c);
digitalWrite(RW, LOW); // R/W set to LOW for writing
digitalWrite(E, HIGH); //E set HIGH for latch
delayMicroseconds(1);
digitalWrite(E, LOW); // E set LOW for latch
break;
case 1: digitalWrite(DC, LOW); //D/C LOW
digitalWrite(E, HIGH); //RD# HIGH
delayMicroseconds(1);
write_8bit(c);
digitalWrite(RW, LOW); //WR LOW
digitalWrite(RW, HIGH); //WR HIGH
break;
case 2: digitalWrite(DC, LOW); //command
for(i=0;i<8;i++)
{
digitalWrite(DB0, LOW);
if((c & mask) >> 7 == 1)
{
digitalWrite(DB1, HIGH);
}
else
{
digitalWrite(DB1, LOW);
}
digitalWrite(DB0, HIGH);
c = c << 1;
}
break;
case 3: I2C_Start_Transmission();
I2C_Transmission_Out(0x78);
I2C_Ack_Ignore(); //SDAout disconnected
I2C_Transmission_Out(0x00);
I2C_Ack_Ignore(); //SDAout disconnected
I2C_Transmission_Out(c);
I2C_Ack_Ignore(); //SDAout disconnected
I2C_Stop_Transmission();
break;
}
}
void data(unsigned char d) // send data to OLED
{
unsigned char i;
unsigned char mask = 0x80;
switch (interface)
{
case 0: write_8bit(d);
digitalWrite(DC, HIGH); // D/C set to HIGH for data_out_2
delayMicroseconds(1);
digitalWrite(RW, LOW); // R/W set to LOW for writing
digitalWrite(E, HIGH); //E set HIGH for latch
delayMicroseconds(1);
digitalWrite(E, LOW); // E set LOW for latch
break;
case 1: digitalWrite(DC, HIGH); //DC HIGH
digitalWrite(E, HIGH); //RD# HIGH
write_8bit(d);
digitalWrite(RW, LOW); //WR LOW
digitalWrite(RW, HIGH); //WR HIGH
break;
case 2: digitalWrite(DC, HIGH);
for(i=0;i<8;i++)
{
digitalWrite(DB0, LOW);
if((d & mask) >> 7 == 1)
{
digitalWrite(DB1, HIGH);
}
else
{
digitalWrite(DB1, LOW);
}
digitalWrite(DB0, HIGH);
d = d << 1;
}
break;
case 3: I2C_Start_Transmission();
I2C_Transmission_Out(0x78);
I2C_Ack_Ignore();
I2C_Transmission_Out(0x40);
I2C_Ack_Ignore();
I2C_Transmission_Out(d);
I2C_Ack_Ignore();
I2C_Stop_Transmission();
break;
}
}
void I2C_Start_Transmission()
{
digitalWrite(DB0, HIGH);
while(0);
digitalWrite(DB1, HIGH);
while(0);
digitalWrite(DB1, LOW);
while(0);
}
void I2C_Transmission_Out(unsigned char b)
{
unsigned int n;
for(n=0;n<8;n++){
if((b&0x80)==0x80)
digitalWrite(DB1, HIGH);
else
digitalWrite(DB1, LOW);
while(0);
b=(b<<1);
digitalWrite(DB0, LOW);
while(0);
digitalWrite(DB0, HIGH);
while(0);
digitalWrite(DB0, LOW);
while(0);
}
}
void I2C_Ack_Ignore()
{
digitalWrite(DB0, LOW);
while(0);
digitalWrite(DB0, HIGH);
while(0);
digitalWrite(DB0, LOW);
while(0);
}
void I2C_Stop_Transmission()
{
digitalWrite(DB0, HIGH);
while(0);
digitalWrite(DB1, LOW);
while(0);
digitalWrite(DB1, HIGH);
while(0);
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Instruction Setting
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void Set_Column_Address(unsigned char a, unsigned char b)
{
command(0x15); // Set Column Address
data(a); //
data(b); //
}
void Set_Row_Address(unsigned char a, unsigned char b)
{
command(0x75); // Set Row Address
data(a); //
data(b); //
}
void Set_Write_RAM()
{
command(0x5C); // Enable MCU to Write into RAM
}
void Set_Read_RAM()
{
command(0x5D); // Enable MCU to Read from RAM
}
void Set_Remap_Format(unsigned char d)
{
command(0xA0); // Set Re-Map / Color Depth
data(d); // Default => 0x50
// Horizontal Address Increment
// Column Address 0 Mapped to SEG0
// Color Sequence: A => B => C
// Scan from COM0 to COM[N-1]
// Enable COM Split Odd Even
// 65,536 Colors
}
void Set_Start_Line(unsigned char d)
{
command(0xA1); // Set Vertical Scroll by RAM
data(d); // Default => 0x00
}
void Set_Display_Offset(unsigned char d)
{
command(0xA2); // Set Vertical Scroll by Row
data(d); // Default => 0x00
}
void Set_Display_Mode(unsigned char d)
{
command(d); // Set Display Mode
// Default => 0xA6
// 0xA4 => Entire Display Off, All Pixels Turn Off
// 0xA5 => Entire Display On, All Pixels Turn On at GS Level 63
// 0xA6 => Normal Display
// 0xA7 => Inverse Display
}
void Set_IREF(unsigned char d)
{
command(0xAD); // Set IREF
data(d); // Default => 0x80
// 0x80 => Select External IREF
// 0x90 => Enable Internal IREF during Display On
}
void Set_Display_On_Off(unsigned char d)
{
command(d); // Set Display On/Off
// Default => 0xAE
// 0xAE => Display Off (Sleep Mode On)
// 0xAF => Display On (Sleep Mode Off)
}
void Set_Phase_Length(unsigned char d)
{
command(0xB1); // Phase 1 (Reset) & Phase 2 (Pre-Charge) Period Adjustment
data(d); // Default => 0x84 (16 Display Clocks [Phase 2] / 8 Display Clocks [Phase 1])
// D[3:0] => Phase 1 Period in 2~30 Display Clocks
// D[7:4] => Phase 2 Period in 2~30 Display Clocks
}
void Set_Display_Clock(unsigned char d)
{
command(0xB3); // Set Display Clock Divider / Oscillator Frequency
data(d); // Default => 0x90
// A[3:0] => Display Clock Divider
// A[7:4] => Oscillator Frequency
}
void Set_Precharge_Period(unsigned char d)
{
command(0xB6); // Set Second Pre-Charge Period
data(d); // Default => 0x08 (8 Display Clocks)
}
void Set_Precharge_Voltage(unsigned char d)
{
command(0xBB); // Set Pre-Charge Voltage Level
data(d); // Default => 0x17 (0.40*VCC)
}
void Set_VCOMH(unsigned char d)
{
command(0xBE); // Set COM Deselect Voltage Level
data(d); // Default => 0x05 (0.82*VCC)
}
void Set_Contrast_Color(unsigned char a, unsigned char b, unsigned char c)
{
command(0xC1); // Set Contrast Current for Color A, B, C
data(a); // Default => 0x7F (Color A)
data(b); // Default => 0x7F (Color B)
data(c); // Default => 0x7F (Color C)
}
void Set_Master_Current(unsigned char d)
{
command(0xC7); // Master Contrast Current Control
data(d); // Default => 0x0F (Maximum)
}
void Set_Multiplex_Ratio(unsigned char d)
{
command(0xCA); // Set Multiplex Ratio
data(d); // Default => 0xAF (1/176 Duty)
}
void Set_Command_Lock(unsigned char d)
{
command(0xFD); // Set Command Lock
data(d); // Default => 0x12
// 0x12 => Driver IC interface is unlocked from entering command.
// 0x16 => All Commands are locked except 0xFD.
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Show Regular Pattern (Full Screen)
//
// a: RRRRRGGG
// b: GGGBBBBB
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void Fill_RAM(unsigned char a, unsigned char b)
{
unsigned char i,j;
Set_Column_Address(0x08,0xA7);
Set_Row_Address(0x00,0x7F);
Set_Write_RAM();
for(i=0;i<128;i++)
{
for(j=0;j<160;j++)
{
data(a);
data(b);
}
}
}
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Sleep Mode
//
// "0x00" Enter Sleep Mode
// "0x01" Exit Sleep Mode
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
void OLED_Sleep(unsigned char a)
{
switch(a)
{
case 0:
Set_Display_On_Off(0xAE);
Set_Display_Mode(0xA5);
break;
case 1:
Set_Display_Mode(0xA6);
Set_Display_On_Off(0xAF);
break;
}
}
void Init_OLED(void)
{
unsigned char i;
digitalWrite(RES,LOW);//RES
delay(10);
digitalWrite(RES,HIGH);//RES
Set_Command_Lock(0x12); // Unlock Driver IC (0x12/0x16)
Set_Display_On_Off(0xAE); // Display Off
Set_Remap_Format(0x74); // Set Horizontal Address Increment
Set_Start_Line(0x00); // Set Mapping RAM Display Start Line
Set_Display_Offset(0x30); // Shift Mapping RAM Counter
Set_Display_Mode(0xA6); // Normal Display Mode
Set_Phase_Length(0x22); // Set Phase 1 & Phase 2
Set_Display_Clock(0xD1); // Set Clock
Set_Precharge_Period(0x08); // Set Second Pre-Charge Period
Set_Precharge_Voltage(0x17); // Set Pre-Charge Voltage Level
Set_VCOMH(0x05); // Set Common Pins Deselect Voltage Level
Set_Contrast_Color(0x45,0x43,0x90); // Set Contrast of Color A (Red), Color B (Green), and Color C (Blue)
Set_Master_Current(0x0F); // Set Scale Factor of Segment Output Current Control
Set_Multiplex_Ratio(0x7F); // 1/128 Duty (Max_Row)
command(0xB8); //Gamma Look-Up Table
data(0x02); // Gray Scale Level 1
data(0x03); // Gray Scale Level 2
data(0x04); // Gray Scale Level 3
data(0x05); // Gray Scale Level 4
data(0x06); // Gray Scale Level 5
data(0x07); // Gray Scale Level 6
data(0x08); // Gray Scale Level 7
data(0x09); // Gray Scale Level 8
data(0x0A); // Gray Scale Level 9
data(0x0B); // Gray Scale Level 10
data(0x0C); // Gray Scale Level 11
data(0x0D); // Gray Scale Level 12
data(0x0E); // Gray Scale Level 13
data(0x0F); // Gray Scale Level 14
data(0x10); // Gray Scale Level 15
data(0x11); // Gray Scale Level 16
data(0x12); // Gray Scale Level 17
data(0x13); // Gray Scale Level 18
data(0x15); // Gray Scale Level 19
data(0x17); // Gray Scale Level 20
data(0x19); // Gray Scale Level 21
data(0x1B); // Gray Scale Level 22
data(0x1D); // Gray Scale Level 23
data(0x1F); // Gray Scale Level 24
data(0x21); // Gray Scale Level 25
data(0x23); // Gray Scale Level 26
data(0x25); // Gray Scale Level 27
data(0x27); // Gray Scale Level 28
data(0x2A); // Gray Scale Level 29
data(0x2D); // Gray Scale Level 30
data(0x30); // Gray Scale Level 31
data(0x33); // Gray Scale Level 32
data(0x36); // Gray Scale Level 33
data(0x39); // Gray Scale Level 34
data(0x3C); // Gray Scale Level 35
data(0x3F); // Gray Scale Level 36
data(0x42); // Gray Scale Level 37
data(0x45); // Gray Scale Level 38
data(0x48); // Gray Scale Level 39
data(0x4C); // Gray Scale Level 40
data(0x50); // Gray Scale Level 41
data(0x54); // Gray Scale Level 42
data(0x58); // Gray Scale Level 43
data(0x5C); // Gray Scale Level 44
data(0x60); // Gray Scale Level 45
data(0x64); // Gray Scale Level 46
data(0x68); // Gray Scale Level 47
data(0x6C); // Gray Scale Level 48
data(0x70); // Gray Scale Level 49
data(0x74); // Gray Scale Level 50
data(0x78); // Gray Scale Level 51
data(0x7D); // Gray Scale Level 52
data(0x82); // Gray Scale Level 53
data(0x87); // Gray Scale Level 54
data(0x8C); // Gray Scale Level 55
data(0x91); // Gray Scale Level 56
data(0x96); // Gray Scale Level 57
data(0x9B); // Gray Scale Level 58
data(0xA0); // Gray Scale Level 59
data(0xA5); // Gray Scale Level 60
data(0xAA); // Gray Scale Level 61
data(0xAF); // Gray Scale Level 62
data(0xB4); // Gray Scale Level 63
Set_Display_On_Off(0xAF); // Display On
}
void Init() // for Arduino, runs first at power on
{
pinMode(DC, OUTPUT); //RS
pinMode(RW, OUTPUT); //RW
pinMode(E, OUTPUT); //E
pinMode(DB0, OUTPUT); //DB0
pinMode(DB1, OUTPUT); //DB1
pinMode(DB2, OUTPUT); //DB2
pinMode(DB3,OUTPUT); //DB3
pinMode(DB4,OUTPUT); //DB4
pinMode(DB5,OUTPUT); //DB5
pinMode(DB6,OUTPUT); //DB6
pinMode(DB7,OUTPUT); //DB7
pinMode(RES,OUTPUT); //RES
pinMode(CS,OUTPUT); //CS
pinMode(BS1,OUTPUT); //BS1
pinMode(BS2,OUTPUT); //BS2
digitalWrite(RES,HIGH); //RES
digitalWrite(CS,LOW); //CS
switch(interface)
{
case 0: digitalWrite(BS1,LOW);//6800 PARALLEL INTERFACE
digitalWrite(BS2,HIGH);//6800 PARALLEL INTERFACE
break;
case 1: digitalWrite(BS1,HIGH);//8080 PARALLEL INTERFACE
digitalWrite(BS2,HIGH);//8080 PARALLEL INTERFACE
break;
case 2: digitalWrite(BS1,LOW);//4-Wire SPI INTERFACE
digitalWrite(BS2,LOW);//4-Wire SPI INTERFACE
digitalWrite(DB2, LOW);
digitalWrite(DB3, LOW);
digitalWrite(DB4, LOW);
digitalWrite(DB5, LOW);
digitalWrite(DB6, LOW);
digitalWrite(DB7, LOW);
digitalWrite(RW, LOW);
digitalWrite(E, LOW);
break;
case 3: digitalWrite(BS1,HIGH);//I2C INTERFACE
digitalWrite(BS2,LOW);//I2C INTERFACE
digitalWrite(DB3, LOW);
digitalWrite(DB4, LOW);
digitalWrite(DB5, LOW);
digitalWrite(DB6, LOW);
digitalWrite(DB7, LOW);
digitalWrite(RW, LOW);
digitalWrite(E, LOW);
digitalWrite(CS, LOW);
break;
}
Init_OLED(); // initialize display
}
void setup() {
Init();
}
void loop()
{
Fill_RAM(WHITE);
Fill_RAM(RED);
Fill_RAM(ORANGE);
Fill_RAM(YELLOW);
Fill_RAM(GREEN);
Fill_RAM(BLUE);
Fill_RAM(VIOLET);
Fill_RAM(BLACK);
}