/* / Program for writing to NHD-0.95-9664G OLED with SSD1331 controller. / This code is written for the Arduino UNO using Serial Interface. / Logic level shifters are required to convert 5V logic to 3.3V / / Newhaven Display invests time and resources providing this open source code, / Please support Newhaven Display by purchasing products from Newhaven Display! * Copyright (c) 2024, 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. * */ enum { _clkfreq = 200000000 }; /**************************************************** * PINOUT: 0.95" OLED -> Arduino Uno * ****************************************************/ #define DC 10 //8 // Data/Command Signal #define RES 9 //9 // Reset Signal #define CS 8 //10 // Chip Select Signal #define SDIN 12 //11 // Serial Data Signal #define SCK 11 //13 // Serial Clock Signal /**************************************************** * Custom Characters * *****************************************************/ unsigned char Ascii_1[97][5] = { // Refer to "Times New Roman" Font Database... // Basic Characters {0x00,0x00,0x00,0x00,0x00}, // ( 0) - 0x0000 Empty set {0x00,0x00,0x4F,0x00,0x00}, // ( 1) ! - 0x0021 Exclamation Mark {0x00,0x07,0x00,0x07,0x00}, // ( 2) " - 0x0022 Quotation Mark {0x14,0x7F,0x14,0x7F,0x14}, // ( 3) # - 0x0023 Number Sign {0x24,0x2A,0x7F,0x2A,0x12}, // ( 4) $ - 0x0024 Dollar Sign {0x23,0x13,0x08,0x64,0x62}, // ( 5) % - 0x0025 Percent Sign {0x36,0x49,0x55,0x22,0x50}, // ( 6) & - 0x0026 Ampersand {0x00,0x05,0x03,0x00,0x00}, // ( 7) ' - 0x0027 Apostrophe {0x00,0x1C,0x22,0x41,0x00}, // ( 8) ( - 0x0028 Left Parenthesis {0x00,0x41,0x22,0x1C,0x00}, // ( 9) ) - 0x0029 Right Parenthesis {0x14,0x08,0x3E,0x08,0x14}, // ( 10) * - 0x002A Asterisk {0x08,0x08,0x3E,0x08,0x08}, // ( 11) + - 0x002B Plus Sign {0x00,0x50,0x30,0x00,0x00}, // ( 12) , - 0x002C Comma {0x08,0x08,0x08,0x08,0x08}, // ( 13) - - 0x002D Hyphen-Minus {0x00,0x60,0x60,0x00,0x00}, // ( 14) . - 0x002E Full Stop {0x20,0x10,0x08,0x04,0x02}, // ( 15) / - 0x002F Solidus {0x3E,0x51,0x49,0x45,0x3E}, // ( 16) 0 - 0x0030 Digit Zero {0x00,0x42,0x7F,0x40,0x00}, // ( 17) 1 - 0x0031 Digit One {0x42,0x61,0x51,0x49,0x46}, // ( 18) 2 - 0x0032 Digit Two {0x21,0x41,0x45,0x4B,0x31}, // ( 19) 3 - 0x0033 Digit Three {0x18,0x14,0x12,0x7F,0x10}, // ( 20) 4 - 0x0034 Digit Four {0x27,0x45,0x45,0x45,0x39}, // ( 21) 5 - 0x0035 Digit Five {0x3C,0x4A,0x49,0x49,0x30}, // ( 22) 6 - 0x0036 Digit Six {0x01,0x71,0x09,0x05,0x03}, // ( 23) 7 - 0x0037 Digit Seven {0x36,0x49,0x49,0x49,0x36}, // ( 24) 8 - 0x0038 Digit Eight {0x06,0x49,0x49,0x29,0x1E}, // ( 25) 9 - 0x0039 Dight Nine {0x00,0x36,0x36,0x00,0x00}, // ( 26) : - 0x003A Colon {0x00,0x56,0x36,0x00,0x00}, // ( 27) ; - 0x003B Semicolon {0x08,0x14,0x22,0x41,0x00}, // ( 28) < - 0x003C Less-Than Sign {0x14,0x14,0x14,0x14,0x14}, // ( 29) = - 0x003D Equals Sign {0x00,0x41,0x22,0x14,0x08}, // ( 30) > - 0x003E Greater-Than Sign {0x02,0x01,0x51,0x09,0x06}, // ( 31) ? - 0x003F Question Mark {0x32,0x49,0x79,0x41,0x3E}, // ( 32) @ - 0x0040 Commercial At {0x7E,0x11,0x11,0x11,0x7E}, // ( 33) A - 0x0041 Latin Capital Letter A {0x7F,0x49,0x49,0x49,0x36}, // ( 34) B - 0x0042 Latin Capital Letter B {0x3E,0x41,0x41,0x41,0x22}, // ( 35) C - 0x0043 Latin Capital Letter C {0x7F,0x41,0x41,0x22,0x1C}, // ( 36) D - 0x0044 Latin Capital Letter D {0x7F,0x49,0x49,0x49,0x41}, // ( 37) E - 0x0045 Latin Capital Letter E {0x7F,0x09,0x09,0x09,0x01}, // ( 38) F - 0x0046 Latin Capital Letter F {0x3E,0x41,0x49,0x49,0x7A}, // ( 39) G - 0x0047 Latin Capital Letter G {0x7F,0x08,0x08,0x08,0x7F}, // ( 40) H - 0x0048 Latin Capital Letter H {0x00,0x41,0x7F,0x41,0x00}, // ( 41) I - 0x0049 Latin Capital Letter I {0x20,0x40,0x41,0x3F,0x01}, // ( 42) J - 0x004A Latin Capital Letter J {0x7F,0x08,0x14,0x22,0x41}, // ( 43) K - 0x004B Latin Capital Letter K {0x7F,0x40,0x40,0x40,0x40}, // ( 44) L - 0x004C Latin Capital Letter L {0x7F,0x02,0x0C,0x02,0x7F}, // ( 45) M - 0x004D Latin Capital Letter M {0x7F,0x04,0x08,0x10,0x7F}, // ( 46) N - 0x004E Latin Capital Letter N {0x3E,0x41,0x41,0x41,0x3E}, // ( 47) O - 0x004F Latin Capital Letter O {0x7F,0x09,0x09,0x09,0x06}, // ( 48) P - 0x0050 Latin Capital Letter P {0x3E,0x41,0x51,0x21,0x5E}, // ( 49) Q - 0x0051 Latin Capital Letter Q {0x7F,0x09,0x19,0x29,0x46}, // ( 50) R - 0x0052 Latin Capital Letter R {0x46,0x49,0x49,0x49,0x31}, // ( 51) S - 0x0053 Latin Capital Letter S {0x01,0x01,0x7F,0x01,0x01}, // ( 52) T - 0x0054 Latin Capital Letter T {0x3F,0x40,0x40,0x40,0x3F}, // ( 53) U - 0x0055 Latin Capital Letter U {0x1F,0x20,0x40,0x20,0x1F}, // ( 54) V - 0x0056 Latin Capital Letter V {0x3F,0x40,0x38,0x40,0x3F}, // ( 55) W - 0x0057 Latin Capital Letter W {0x63,0x14,0x08,0x14,0x63}, // ( 56) X - 0x0058 Latin Capital Letter X {0x07,0x08,0x70,0x08,0x07}, // ( 57) Y - 0x0059 Latin Capital Letter Y {0x61,0x51,0x49,0x45,0x43}, // ( 58) Z - 0x005A Latin Capital Letter Z {0x00,0x7F,0x41,0x41,0x00}, // ( 59) [ - 0x005B Left Square Bracket {0x02,0x04,0x08,0x10,0x20}, // ( 60) \ - 0x005C Reverse Solidus {0x00,0x41,0x41,0x7F,0x00}, // ( 61) ] - 0x005D Right Square Bracket {0x04,0x02,0x01,0x02,0x04}, // ( 62) ^ - 0x005E Circumflex Accent {0x40,0x40,0x40,0x40,0x40}, // ( 63) _ - 0x005F Low Line {0x01,0x02,0x04,0x00,0x00}, // ( 64) ` - 0x0060 Grave Accent {0x20,0x54,0x54,0x54,0x78}, // ( 65) a - 0x0061 Latin Small Letter A {0x7F,0x48,0x44,0x44,0x38}, // ( 66) b - 0x0062 Latin Small Letter B {0x38,0x44,0x44,0x44,0x20}, // ( 67) c - 0x0063 Latin Small Letter C {0x38,0x44,0x44,0x48,0x7F}, // ( 68) d - 0x0064 Latin Small Letter D {0x38,0x54,0x54,0x54,0x18}, // ( 69) e - 0x0065 Latin Small Letter E {0x08,0x7E,0x09,0x01,0x02}, // ( 70) f - 0x0066 Latin Small Letter F {0x06,0x49,0x49,0x49,0x3F}, // ( 71) g - 0x0067 Latin Small Letter G {0x7F,0x08,0x04,0x04,0x78}, // ( 72) h - 0x0068 Latin Small Letter H {0x00,0x44,0x7D,0x40,0x00}, // ( 73) i - 0x0069 Latin Small Letter I {0x20,0x40,0x44,0x3D,0x00}, // ( 74) j - 0x006A Latin Small Letter J {0x7F,0x10,0x28,0x44,0x00}, // ( 75) k - 0x006B Latin Small Letter K {0x00,0x41,0x7F,0x40,0x00}, // ( 76) l - 0x006C Latin Small Letter L {0x7C,0x04,0x18,0x04,0x7C}, // ( 77) m - 0x006D Latin Small Letter M {0x7C,0x08,0x04,0x04,0x78}, // ( 78) n - 0x006E Latin Small Letter N {0x38,0x44,0x44,0x44,0x38}, // ( 79) o - 0x006F Latin Small Letter O {0x7C,0x14,0x14,0x14,0x08}, // ( 80) p - 0x0070 Latin Small Letter P {0x08,0x14,0x14,0x18,0x7C}, // ( 81) q - 0x0071 Latin Small Letter Q {0x7C,0x08,0x04,0x04,0x08}, // ( 82) r - 0x0072 Latin Small Letter R {0x48,0x54,0x54,0x54,0x20}, // ( 83) s - 0x0073 Latin Small Letter S {0x04,0x3F,0x44,0x40,0x20}, // ( 84) t - 0x0074 Latin Small Letter T {0x3C,0x40,0x40,0x20,0x7C}, // ( 85) u - 0x0075 Latin Small Letter U {0x1C,0x20,0x40,0x20,0x1C}, // ( 86) v - 0x0076 Latin Small Letter V {0x3C,0x40,0x30,0x40,0x3C}, // ( 87) w - 0x0077 Latin Small Letter W {0x44,0x28,0x10,0x28,0x44}, // ( 88) x - 0x0078 Latin Small Letter X {0x0C,0x50,0x50,0x50,0x3C}, // ( 89) y - 0x0079 Latin Small Letter Y {0x44,0x64,0x54,0x4C,0x44}, // ( 90) z - 0x007A Latin Small Letter Z {0x00,0x08,0x36,0x41,0x00}, // ( 91) { - 0x007B Left Curly Bracket {0x00,0x00,0x7F,0x00,0x00}, // ( 92) | - 0x007C Vertical Line {0x00,0x41,0x36,0x08,0x00}, // ( 93) } - 0x007D Right Curly Bracket {0x02,0x01,0x02,0x04,0x02}, // ( 94) ~ - 0x007E Tilde {0x08,0x0C,0x0E,0x0C,0x08}, // ( 95) upward facing triangle/arrow {0x08,0x18,0x38,0x18,0x08}, // ( 96) downward facing triangle/arrow }; /**************************************************** * Function Commands * *****************************************************/ void command(unsigned char c){ _pinl(CS); //digitalWrite(CS,LOW); //Start Write _pinl(DC); //digitalWrite(DC,LOW); //Set Command Write for(int i=0; i<8; i++){ //Write _pinl(SCK); ///digitalWrite(SCK,LOW); if((c & 0x80) >> 7 == 1){ _pinh(SDIN); //digitalWrite(SDIN,HIGH); }else{ _pinl(SDIN); //digitalWrite(SDIN,LOW); } _pinh(SCK); //digitalWrite(SCK,HIGH); c = c << 1; } _pinh(CS); //digitalWrite(CS,HIGH); //End Write } void data(unsigned char d){ _pinl(CS); //digitalWrite(CS,LOW); //Start Write _pinh(DC); //digitalWrite(DC,HIGH); //Set Data Write for(int i=0; i<8; i++){ _pinl(SCK);// digitalWrite(SCK,LOW); //Write if((d & 0x80) >> 7 == 1){ _pinh(SDIN);//digitalWrite(SDIN,HIGH); }else{ _pinl(SDIN);//digitalWrite(SDIN,LOW); } _pinh(SCK);//digitalWrite(SCK,HIGH); d = d << 1; } _pinh(CS);//digitalWrite(CS,HIGH); //End Write } /**************************************************** * Display Commands * *****************************************************/ void Set_CommandLock(){ command(0xFD); //Command Unlock command(0x12); } void Set_DisplayOn(){ command(0xAF); //Set Display OFF } void Set_DisplayOff(){ command(0xAE); //Set Display OFF } void Set_DisplayClkDivideRatio(){ command(0xB3); //Set Display Clock Divide Ratio/Oscillator Frequency command(0xF0); } void Set_MultiplexRatio(){ command(0xA8); //Set MUX Ratio command(0x3F); } void Set_DisplayOffset(){ command(0xA2); //Set Display Offset command(0x00); } void Set_DisplayStartLine(){ command(0xA1); //Set Display Start Line command(0x00); } void Set_ColumnAddress(unsigned char col_start, unsigned char col_end){ command(0x15); command(col_start); command(col_end); } void Set_RowAddress(unsigned char row_start, unsigned char row_end){ command(0x75); command(row_start); command(row_end); } void Set_Remap(){ command(0xA0); //Set Re-map & Color Depth command(0x74); } void Set_MasterConfig(){ command(0xAD); //Set Master Configuration command(0x8E); } void PowerSaveMode(){ command(0xB0); //Set Power Saving Mode command(0x0B); } void Set_ContrastCurrentA(){ command(0x81); //Set Contrast Current for A command(0x91); } void Set_ContrastCurrentB(){ command(0x82); //Set Contrast Current for B command(0x50); } void Set_ContrastCurrentC(){ command(0x83); //Set Contrast Current for C command(0x7D); } void MasterCurrentControl(){ command(0x87); //Master Current Control command(0x06); } void Set_PhaseLength(){ command(0xB1); //Set Phase Length command(0x31); } void Set_PreChargeVoltage(){ command(0xBB); //Set Pre-charge Voltage command(0x3A); } void Set_SecondPrechargeABC(){ command(0x8A); //Set Second Pre-Charge Speed for Color A command(0x64); command(0x8B); //Set Second Pre-Charge Speed for Color B command(0x78); command(0x8C); //Set Second Pre-Charge Speed for Color C command(0x64); } void Set_VCOMH(){ command(0xBE); //Set VCOMH command(0x3E); } void Set_DisplayMode(){ command(0xA4); //Set Display Mode } void DrawRectangle(){ command(0x22); command(0x00); //Column Start command(0x00); //Row Start command(0x5F); //Column End command(0x3F); //Row End // Line Colors command(0xFF); // C command(0xFF); // B command(0xFF); // A // Area Fill Colors // command(0xFF); // C // command(0xFF); // B // command(0xFF); // A } void ClearWindow(){ command(0x25); command(0x00); //Column Address of Start command(0x00); //Row Address of Start command(0x5F); //Column Address of End command(0x3F); //Row Address of End } /**************************************************** * Display Functions * *****************************************************/ void DrawText(unsigned char column, unsigned char row, unsigned char letter){ unsigned int i,j; unsigned char reg = 0x80; for(i=0; i <8; i++){ // Pixel height Set_ColumnAddress(column,0x5F); // Start Column, End at Column 95 Set_RowAddress(row,0x3F); // Start Row, End at Row 63 for(j=0; j <5; j++){ // Pixel Width if((Ascii_1[letter][j] & reg) == reg){ data(0x0F); //Display Green _waitus(100);//delayMicroseconds(100); data(0x80); _waitus(100);//delayMicroseconds(100); } else{ data(0x00); //Display Black _waitus(100);//delayMicroseconds(100); data(0x00); _waitus(100);//delayMicroseconds(100); } } row++; reg = reg >> 1; } _waitms(100);//delay(100); } void DisplayColor(unsigned char ColorA, unsigned char ColorB){ unsigned int i,j; Set_ColumnAddress(0x00,0x5F); // Start at Column 0, End at Column 95 Set_RowAddress(0x00,0x3F); // Start at Row 0, End at Row 63 for(i=0; i< 95; i++){ //Columns for(j=0; j<129; j++){ //Rows data(ColorA); //Set Color _waitus(10);//delayMicroseconds(10); data(ColorB); _waitus(10);//delayMicroseconds(10); } } DrawRectangle(); _waitms(100);//delay(100); } void DisplaySpectrum(){ unsigned int i,j; Set_ColumnAddress(0x00,0x5F); // Start at Column 0, End at Column 95 Set_RowAddress(0x00,0x3F); // Start at Row 0, End at Row 63 for(i=0; i< 96; i++){ //Columns for(j=0; j<16; j++){ //Rows data(0x00); //Display Red _waitus(100);//delayMicroseconds(100); data(0xFF); _waitus(100);//delayMicroseconds(100); } } for(i=0; i< 96; i++){ //Columns for(j=0; j<16; j++){ //Rows data(0x0F); //Display Yellow _waitus(100);//delayMicroseconds(100); data(0xFF); _waitus(100);//delayMicroseconds(100); } } for(i=0; i< 96; i++){ //Columns for(j=0; j<16; j++){ //Rows data(0x0F); //Display Green _waitus(100);//delayMicroseconds(100); data(0x80); _waitus(100);//delayMicroseconds(100); } } for(i=0; i< 96; i++){ //Columns for(j=0; j<16; j++){ //Rows data(0xF8); //Display Blue _waitus(100);//delayMicroseconds(100); data(0x00); _waitus(100);//delayMicroseconds(100); } } _waitms(5000);//delay(5000); } /**************************************************** * Set-up Functions * *****************************************************/ void Init(){ Set_CommandLock(); //Unlock //Set Command Lock Set_DisplayOff(); //OFF //Set Display On/Off Set_DisplayClkDivideRatio(); //Display Clock Divider / Oscillator Frequency Set_MultiplexRatio(); //Set Multiplex Ratio Set_DisplayOffset(); //Set Display Offset Set_DisplayStartLine(); //00d //Set Display Start Line Set_Remap(); //Mirror //Remap & Color Depth Setting: Display Orientation Set_MasterConfig(); //Set Master Configuration PowerSaveMode(); //Enable //Power Save Mode: Set_ContrastCurrentA(); //Set Contrast for Color "A" Set_ContrastCurrentB(); //Set Contrast for Color "B" Set_ContrastCurrentC(); //Set Contrast for Color "C" MasterCurrentControl(); //Master Current Control Set_PhaseLength(); //Phase 1 and 2 period adjustment Set_PreChargeVoltage(); //Set Pre-charge level Set_SecondPrechargeABC(); //Set Second Pre-Charge Speed for Color "A","B" and "C" Set_VCOMH(); //Set VCOMH Set_DisplayMode(); //Normal //Set Display Mode ClearWindow(); //Clear Window Set_DisplayOn(); //On //Set Display On/Off _waitms(100);//delay(100); } void setup(){ //Set Ports of Arduino UNO as Outputs //DDRB = 0xFF; //PORTB = 0x00; _pinl(CS);//digitalWrite(CS, LOW); _pinl(RES);//digitalWrite(RES, LOW); _waitms(300);//delay(300); _pinh(RES);//digitalWrite(RES, HIGH); _waitms(120);//delay(120); Init(); //Initial Screen: Newhaven Display International DrawText(0x0D,0x28,46); //N DrawText(0x14,0x28,69); //e DrawText(0x1B,0x28,87); //w DrawText(0x22,0x28,72); //h DrawText(0x29,0x28,65); //a DrawText(0x30,0x28,86); //v DrawText(0x37,0x28,69); //e DrawText(0x3E,0x28,78); //n DrawText(0x0D,0x19,36); //D DrawText(0x14,0x19,73); //i DrawText(0x1B,0x19,83); //s DrawText(0x22,0x19,80); //p DrawText(0x29,0x19,76); //l DrawText(0x30,0x19,65); //a DrawText(0x37,0x19,89); //y DrawText(0x08,0x0A,41); //I DrawText(0x0F,0x0A,78); //n DrawText(0x16,0x0A,84); //t DrawText(0x1D,0x0A,69); //e DrawText(0x24,0x0A,82); //r DrawText(0x2B,0x0A,78); //n DrawText(0x32,0x0A,65); //a DrawText(0x39,0x0A,84); //t DrawText(0x40,0x0A,73); //i DrawText(0x47,0x0A,79); //o DrawText(0x4E,0x0A,78); //n DrawText(0x55,0x0A,65); //a DrawText(0x5C,0x0A,76); //l _waitms(2500);//delay(2500); ClearWindow(); } void loop() { DisplayColor(0x00,0xFF); //Display Red ClearWindow(); _waitms(500);//delay(500); DisplayColor(0x0F,0x80); //Display Green ClearWindow(); _waitms(500);//delay(500); DisplayColor(0xF8,0x00); //Display Blue ClearWindow(); _waitms(500);//delay(500); DisplaySpectrum(); ClearWindow(); _waitms(500);//delay(500); } void main() { setup(); for (;;) { loop(); } }