I have been building a program using a Newhaven OLED screen (NHD-0420CW) together with RTC over I2C, and a SD card on SPI. I have just changed the screen code through necessity to instead use SPI and have found it doesn't function in my sketch. I have narrowed it down to be the SPI.h and SD.h command functions, but that's where my ability ends. A closer look in some of the .h and .cpp files goes over my head.
There are code examples for this screen which use the SPI.h library but I haven't had any success with those on their own, so my sketch is based on the code included.
Is there an easy way around this?
/*
* Original example created by Newhaven Display International Inc.
* Modified and adapted to Arduino Uno 30 Mar 2015 by Pasquale D'Antini
* Modified 19 May 2015 by Pasquale D'Antini
* This example code is in the public domain.
*/
const byte ROW_N = 4; // Number of display rows
const byte COLUMN_N = 20; // Number of display columns
const byte CS = 2;
const byte RES = 3;
const byte SCLK = 13;
const byte SDIN = 11;
const byte SDOUT = 12;
const byte TEXT[4][21] = {"1-Newhaven Display--",
"2-------Test--------",
"3-16/20-Characters--",
"4!@#$%^&*()_+{}[]<>?"};
byte new_line[4] = {0x80, 0xA0, 0xC0, 0xE0};
byte rows = 0x08; // Display mode 2/4 lines
void command(byte c) //PREPARES TRANSMISSION OF A COMMAND
{
byte i = 0;
for(i=0; i<5; i++)
{
digitalWrite(SDIN, HIGH);
clockCycle();
}
for(i=0; i<3; i++)
{
digitalWrite(SDIN, LOW);
clockCycle();
}
send_byte(c);
}
void data(byte d) // PREPARES THE TRANSMISSION OF DATA
{
byte i = 0;
for(i=0; i<5; i++)
{
digitalWrite(SDIN, HIGH);
clockCycle();
}
digitalWrite(SDIN, LOW);
clockCycle();
digitalWrite(SDIN, HIGH);
clockCycle();
digitalWrite(SDIN, LOW);
clockCycle();
send_byte(d);
}
void send_byte(byte tx_b) //SEND TO THE DISPLAY
{
byte i = 0;
for(i=0; i<4; i++)
{
if((tx_b & 0x01) == 1)
{
digitalWrite(SDIN, HIGH);
}
else
{
digitalWrite(SDIN, LOW);
}
clockCycle();
tx_b = tx_b >> 1;
}
for(i=0; i<4; i++)
{
digitalWrite(SDIN, LOW);
clockCycle();
}
for(i=0; i<4; i++)
{
if((tx_b & 0x1) == 0x1) //Change?
{
digitalWrite(SDIN, HIGH);
}
else
{
digitalWrite(SDIN, LOW);
}
clockCycle();
tx_b = tx_b >> 1;
}
for(i=0; i<4; i++)
{
digitalWrite(SDIN, LOW);
clockCycle();
}
}
void clockCycle(void) //CLOCK SIGNAL CYCLE
{
digitalWrite(CS, LOW);
delayMicroseconds(1);
digitalWrite(SCLK, LOW);
delayMicroseconds(1);
digitalWrite(SCLK, HIGH);
delayMicroseconds(1);
delayMicroseconds(1);
digitalWrite(CS, HIGH);
}
void output(void) //DISPLAYS FOUR STRINGS, THEN IN REVERSE ORDER
{
byte r = 0;
byte c = 0;
command(0x01); // Clears display
delay(2);
for (r=0; r<ROW_N; r++)
{
command(new_line[r]);
for (c=0; c<COLUMN_N; c++)
{
data(TEXT[r][c]);
}
}
delay(2000);
for (r=0; r<ROW_N; r++)
{
command(new_line[r]);
for (c=0; c<COLUMN_N; c++)
{
data(TEXT[3-r][c]);
}
}
}
void setup(void)
{
pinMode(SCLK, OUTPUT);
digitalWrite(SCLK, HIGH);
pinMode(SDIN, OUTPUT);
digitalWrite(SDIN, LOW);
pinMode(SDOUT, INPUT);
pinMode(CS, OUTPUT);
digitalWrite(CS, HIGH);
pinMode(RES, OUTPUT)
digitalWrite(RES, HIGH);
delayMicroseconds(200);
if (ROW_N == 2 || ROW_N == 4)
rows = 0x08; //2/4 lines
else
rows = 0x00; //1/3 lines
command(0x22 | rows); // Function set: extended command set (RE=1), lines #
command(0x71); // Function selection A:
data(0x5C); // enable internal Vdd regulator at 5V I/O mode (def. value) (0x00 for disable, 2.8V I/O)
command(0x20 | rows); // Function set: fundamental command set (RE=0) (exit from extended command set), lines #
command(0x08); // Display ON/OFF control: display off, cursor off, blink off (default values)
command(0x22 | rows); // Function set: extended command set (RE=1), lines #
command(0x79); // OLED characterization: OLED command set enabled (SD=1)
command(0xD5); // Set display clock divide ratio/oscillator frequency:
command(0x70); // divide ratio=1, frequency=7 (default values)
command(0x78); // OLED characterization: OLED command set disabled (SD=0) (exit from OLED command set)
if (ROW_N > 2)
command(0x09); // Extended function set (RE=1): 5-dot font, B/W inverting disabled (def. val.), 3/4 lines
else
command(0x08); // Extended function set (RE=1): 5-dot font, B/W inverting disabled (def. val.), 1/2 lines
command(0x06); // Entry Mode set - COM/SEG direction: COM0->COM31, SEG99->SEG0 (BDC=1, BDS=0)
command(0x72); // Function selection B:
data(0x0A); // ROM/CGRAM selection: ROM C, CGROM=250, CGRAM=6 (ROM=10, OPR=10)
command(0x79); // OLED characterization: OLED command set enabled (SD=1)
command(0xDA); // Set SEG pins hardware configuration:
command(0x10); // alternative odd/even SEG pin, disable SEG left/right remap (default values)
command(0xDC); // Function selection C:
command(0x00); // internal VSL, GPIO input disable
command(0x81); // Set contrast control:
command(0x7F); // contrast=127 (default value)
command(0xD9); // Set phase length:
command(0xF1); // phase2=15, phase1=1 (default: 0x78)
command(0xDB); // Set VCOMH deselect level:
command(0x40); // VCOMH deselect level=1 x Vcc (default: 0x20=0,77 x Vcc)
command(0x78); // OLED characterization: OLED command set disabled (SD=0) (exit from OLED command set)
command(0x20 | rows); // Function set: fundamental command set (RE=0) (exit from extended command set), lines #
command(0x01); // Clear display
delay(2); // After a clear display, a minimum pause of 1-2 ms is required
command(0x80); // Set DDRAM address 0x00 in address counter (cursor home) (default value)
command(0x0C); // Display ON/OFF control: display ON, cursor off, blink off
delay(250); // Waits 250 ms for stabilization purpose after display on
if (ROW_N == 2)
new_line[1] = 0xC0; // DDRAM address for each line of the display (only for 2-line mode)
}
void loop(void) // MAIN PROGRAM
{
output(); // Execute subroutine "output"
delay(2000); // Waits, only for visual effect purpose
blocks(); // Execute subroutine "blocks"
delay(2000); // Waits, only for visual effect purpose
}