//---------------------------------------------------------
/*
Program for writing to Newhaven Display NHD-1.8-160128UBC3 with SSD1353 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.8-160128UBC3 Arduino Due
1 GND
2 3.3V
3 NC
4 D25
5 D26
6 D27
7 D28
8 D29
9 D30
10 D31
11 D32
12 D33
13 D34
14 D35
15 D36
16 D37
17 D38
18 D39
19 D40
20 D41
----------------------------------------------*/
//--------------Interface Selection-----------------------------------------------------------
const unsigned char interface = 0; //0 = Parallel 6800 1 = Parallel 8080 2 = 4-Wire SPI
//--------------------------------------------------------------------------------------------
#define P4 25 //RS
#define P5 26 //R/W
#define P6 27 //E
#define P7 28 //DB0
#define P8 29 //DB1
#define P9 30 //DB2
#define P10 31 //DB3
#define P11 32 //DB4
#define P12 33 //DB5
#define P13 34 //DB6
#define P14 35 //DB7
#define P15 36 //GND
#define P16 37 //RES
#define P17 38 //CS
#define P18 39 //GND
#define P19 40 //BS1
#define P20 41 //BS2
#define WHITE 0xFFFF
#define RED 0xF800
#define ORANGE 0xFBE0
#define YELLOW 0xFFE0
#define GREEN 0x07E0
#define BLUE 0x001F
#define VIOLET 0x781F
#define BLACK 0x0000
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(P4, LOW); // D/C set to LOW for comm_out_2
delayMicroseconds(1);
write_8bit(c);
digitalWrite(P5, LOW); // R/W set to LOW for writing
digitalWrite(P6, HIGH); //E set HIGH for latch
delayMicroseconds(1);
digitalWrite(P6, LOW); // E set LOW for latch
break;
case 1: digitalWrite(P4, LOW); //D/C LOW
digitalWrite(P6, HIGH); //RD# HIGH
delayMicroseconds(1);
write_8bit(c);
digitalWrite(P5, LOW); //WR LOW
digitalWrite(P5, HIGH); //WR HIGH
break;
case 2: digitalWrite(P4, LOW); //command
for(i=0;i<8;i++)
{
digitalWrite(P7, LOW);
if((c & mask) >> 7 == 1)
{
digitalWrite(P8, HIGH);
}
else
{
digitalWrite(P8, LOW);
}
digitalWrite(P7, HIGH);
c = c << 1;
}
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(P4, HIGH); // D/C set to HIGH for data_out_2
delayMicroseconds(1);
digitalWrite(P5, LOW); // R/W set to LOW for writing
digitalWrite(P6, HIGH); //E set HIGH for latch
delayMicroseconds(1);
digitalWrite(P6, LOW); // E set LOW for latch
break;
case 1: digitalWrite(P4, HIGH); //DC HIGH
digitalWrite(P6, HIGH); //RD# HIGH
write_8bit(d);
digitalWrite(P5, LOW); //WR LOW
digitalWrite(P5, HIGH); //WR HIGH
break;
case 2: digitalWrite(P4, HIGH);
for(i=0;i<8;i++)
{
digitalWrite(P7, LOW);
if((d & mask) >> 7 == 1)
{
digitalWrite(P8, HIGH);
}
else
{
digitalWrite(P8, LOW);
}
digitalWrite(P7, HIGH);
d = d << 1;
}
break;
}
}
void SetColumnAddress(unsigned char x_start, unsigned char x_end) // set column address start + end
{
command(0x15);
data(x_start);
data(x_end);
}
void SetRowAddress(unsigned char y_start, unsigned char y_end) // set row address start + end
{
command(0x75);
data(y_start);
data(y_end);
}
void WriteMemoryStart(void) // write to RAM command
{
command(0x5c);
}
void SetPosition(unsigned int x_pos, unsigned int y_pos) // set x,y address
{
command(0x20);
data(x_pos);
command(0x21);
data(y_pos);
}
void FillScreen(uint16_t a) //fill screen with a given color. Use RGB565 format. (Useful resource: https://github.com/newdigate/rgb565_colors)
{
unsigned char i, j,x1,x2;
SetColumnAddress(0x00,0x9F); //Columns 0-159
SetRowAddress(0x00,0x7f); //Rows 0-127
SetPosition(0,0);
WriteMemoryStart();
x1=(a>>8);
x2=(a & 0x00FF);
for (i = 0; i < 128; i++)
{
for (j = 0; j < 160; j++)
{
data(x1);
data(x2);
}
}
}
void Init_OLED()
{
command(0xAE); //Set Display OFF
command(0xA8); //Set MUX ratio
data(0x7F);
command(0xA2); //Set Display offset
data(0x00);
command(0xA1); //Set display start line
data(0x00);
command(0xA4); //Normal display
command(0xA0); //Set Re-map, color depth
data(0x64);
command(0x81); //Set Contrast for color"A" segment
data(0x75);
command(0x82); //Set Contrast for color"B" segment
data(0x60);
command(0x83); //Set Contrast for color"C" segment
data(0x6A);
command(0x87); //Master Contrast Current Control
data(0x0F);
command(0xB9); //use linear grayscale table
command(0xB1); //Set Phase1 and phase2 period adjustment
data(0x22);
command(0xB3); //Set Display Clock Divide Ratio (internal clock selection)
data(0x40);
command(0xBB); //Set Pre-charge Voltage
data(0x08);
command(0xBE); //Set VCOMH
data(0x2F);
command(0xAF); //Set Display ON in mormal mode
}
void Init_Pins()
{
pinMode(P4, OUTPUT);//RS
pinMode(P5, OUTPUT);//R/W
pinMode(P6, OUTPUT);//E
pinMode(P7, OUTPUT);//DB0
pinMode(P8, OUTPUT);//DB1
pinMode(P9, OUTPUT);//DB2
pinMode(P10,OUTPUT);//DB3
pinMode(P11,OUTPUT);//DB4
pinMode(P12,OUTPUT);//DB5
pinMode(P13,OUTPUT);//DB6
pinMode(P14,OUTPUT);//DB7
pinMode(P15,OUTPUT);//GND
pinMode(P16,OUTPUT);//RES
pinMode(P17,OUTPUT);//CS
pinMode(P18,OUTPUT);//GND
pinMode(P19,OUTPUT);//BS1
pinMode(P20,OUTPUT);//BS2
digitalWrite(P15,LOW);
digitalWrite(P16,HIGH);
digitalWrite(P17,LOW);
digitalWrite(P18,LOW);
switch(interface)
{
case 0: digitalWrite(P19,LOW);//6800 PARALLEL INTERFACE
digitalWrite(P20,HIGH);//6800 PARALLEL INTERFACE
break;
case 1: digitalWrite(P19,HIGH);//8080 PARALLEL INTERFACE
digitalWrite(P20,HIGH);//8080 PARALLEL INTERFACE
break;
case 2: digitalWrite(P19,LOW);//4-Wire SPI INTERFACE
digitalWrite(P20,LOW);//4-Wire SPI INTERFACE
digitalWrite(P9, LOW);
digitalWrite(P10, LOW);
digitalWrite(P11, LOW);
digitalWrite(P12, LOW);
digitalWrite(P13, LOW);
digitalWrite(P14, LOW);
digitalWrite(P15, LOW);
digitalWrite(P5, LOW);
digitalWrite(P6, LOW);
break;
}
digitalWrite(P16,LOW);
delay(100);
digitalWrite(P16,HIGH);
delay(1000);
}
void setup() {
Init_Pins();
Init_OLED();
}
void loop()
{
FillScreen(WHITE);
FillScreen(RED);
FillScreen(ORANGE);
FillScreen(YELLOW);
FillScreen(GREEN);
FillScreen(BLUE);
FillScreen(VIOLET);
FillScreen(BLACK);
}