I'm trying to get an NHD OLED display (specficially the NHD-2.7-12864UMY3) working with an Arduino micro and am having difficulties. I know others have been able to get this display working with other Arduino models. I'll get right to it - here's the schematic:
I have everything wired up on a breadboard (except the switches, LM34, and voltage divider going to A0), but the display won't turn on. I've checked all the appropriate voltages and everything looks good.
Any ideas? I've checked and triple checked the Micro documentation and the OLED display documentation and I can't see what I'm missing on the electrical side. I've tried leaving the RST line on the display open, tied to +3.3V, and set up as shown in the schematic. I've even put a 'scope on all the pins and everything appears as it should with nice clean DC +3.3V on the power pin and I can see data on the data pin.
For reference, here's the code loaded on the Micro for testing. I'm sure I've screwed up something here, too, but I don't think that would keep the OLED display from turning on.
#include <SPI.h>
#include <U8glib.h>
// This sketch is for an Arduino Micro based voltmeter and thermometer using an LM34
// connected to a NHD-2.7-12864UMY3 OLED 128x64 display.
// Setup the display driver
// U8GLIB_NHD27OLED_GR u8g(10, 9); // U8GLIB_NHD27OLED_GR(cs, a0 [, reset])
// U8GLIB_NHD27OLED_GR u8g(13, 11, 10, 9); // U8GLIB_NHD27OLED_GR(sck, mosi, cs, a0 [, reset])
// U8GLIB_NHD27OLED_2X_GR u8g(13, 11, 10, 9); // U8GLIB_NHD27OLED_2X_GR(sck, mosi, cs, a0 [, reset])
// Arduino Micro Serial1 pins are different
// U8GLIB_NHD27OLED_2X_GR u8g(15, 16, 17, 9); // U8GLIB_NHD27OLED_GR(sck, mosi, cs, a0 [, reset])
U8GLIB_NHD27OLED_2X_GR u8g(17, 9); // U8GLIB_NHD27OLED_GR(cs, a0 [, reset])
int cnt = 0; // For testing
// SetContrast() stuff
int ContUpState = 0;
int ContDnState = 0;
int ContrastValue = 255; // Start the display at maximum contrast
const int ContrastMin = 50; // Minimum contrast we want to use - 0 is actual HW minimum
const int ContrastMax = 255; // Maximum contrast
const int ContrastStep = 5; // How much to change contrast with each push of the button
unsigned char ContUpPin = 4; // Push button to turn contrast up
unsigned char ContDnPin = 5; // Push button to turn contrast down
// DisplayVoltage() stuff
const int VM_NUM_SAMPLES = 10; // Number of readings to take to average out later
int VMsum = 0; // sum of samples taken
int VMsample_count = 0; // current sample number
unsigned char VMpin = A0; // Use pin A0 for input from 12V after voltage divider - don't exceed 5V actual
float VMvoltage = 0.00; // calculated voltage
float VMout = 0.00; // Voltage output
int VoltWidth = 0; // Width of the voltage reading in pixels
int VoltSpace = 0;
// DisplayTemp() stuff
unsigned char TempPin = A1; // Use pin A1 for input from LM34
int TempWidth = 0; // Width of the temperature reading in pixels
int TempSpace = 0;
void setup() {
Serial1.begin(9600); // Arduino Micro uses Serial1 for hardware serial
// Assign Pins
pinMode(4, INPUT_PULLUP); // Push button to turn contrast up
digitalWrite(4, HIGH); // Turn on internal Pull-Up Resistor
pinMode(5, INPUT_PULLUP); // Push button to turn contrast down
digitalWrite(5, HIGH); // Turn on internal Pull-Up Resistor
pinMode(9, OUTPUT); // Data out to OLED display - SPI2_SI on NHD display
pinMode(10, OUTPUT); // CS out to display
// A0 - Input for DisplayVoltage()
// A1 - Input for DisplayTemp()
// Testing stuff
u8g.begin();
u8g.setContrast(255);
u8g.setColorIndex(1);
delay(5000);
u8g.setColorIndex(0);
delay(5000);
u8g.setContrast(127);
u8g.setColorIndex(1);
delay(5000);
u8g.setColorIndex(0);
delay(5000);
u8g.setContrast(255);
}
void DisplayVoltage() {
// take a number of analog samples and add them up
while (VMsample_count < VM_NUM_SAMPLES) {
VMsum += analogRead(VMpin); // Read the voltage and add it to the previous readings
VMsample_count++; // Increment the counter
delay(10);
}
// Calculate the voltage
// Use 5.0 for a 5.0V ADC reference voltage
// 5.015V is the calibrated reference voltage
VMvoltage = ((float)VMsum / (float)VM_NUM_SAMPLES * 5.015) / 1024.0;
// Send voltage for display
// Voltage multiplied by 11 when using voltage divider that
// divides by 11. 11.132 is the calibrated voltage divide
// value
VMout = VMvoltage * 11.132;
VoltWidth = u8g.getStrWidth("VMout"); // How wide is the voltage reading in pixels
VoltSpace = VoltWidth + 5;
u8g.setFontPosTop(); // Set 0,0 at upper left
u8g.setFont(u8g_font_9x15Br); // Set the font - 9X15 bold
u8g.setPrintPos(0, 30); // Start in the upper left corner
u8g.print(VMout); // Print the voltage
u8g.setFont(u8g_font_9x15r); // Set the font - 9x15 regular
u8g.setPrintPos(VoltSpace, 30); // Set the position for the next line
u8g.print("V"); // Print V next to the voltage reading
// Reset the counter variables
VMsample_count = 0;
VMsum = 0;
}
void DisplayTemp() {
int rawvoltage = analogRead(TempPin); // Read the volage from the LM34 - 1.000V = 100 deg F
float millivolts = (rawvoltage/1024.0) * 5000;
float DegF = millivolts/10;
TempWidth = u8g.getStrWidth("DegF"); // How wide is the temperature reading in pixels
TempSpace = TempWidth + 5;
u8g.setFontPosTop(); // Set 0,0 at upper left
u8g.setFont(u8g_font_9x15Br); // Set the font
u8g.setPrintPos(63, 30); // Set the print position for the reading
u8g.print(DegF); // Print the temperature
u8g.setFont(u8g_font_9x15r); // Set the font
u8g.setPrintPos(TempSpace, 30); // Set the print position for the next line
u8g.print("F"); // Print F next to the temp reading
delay(1000); // wait 1 sec between updates
}
void SetContrast() {
// Read the state of the contrast buttons
ContUpState = digitalRead(ContUpPin);
ContDnState = digitalRead(ContDnPin);
// Check if one of the contrast buttons is pressed.
// If it is, the button state is LOW
if (ContUpState == LOW) { // Contrast up button is pushed
if (ContrastValue >= ContrastMin) { // Check to make sure is not all the way down already
ContrastValue == ContrastValue + ContrastStep; // Adjust the contrast up by one step
u8g.setContrast(ContrastValue); // Send the new contrast value to the display
}
}
if (ContDnState == LOW) { // Contrast down button is pushed
if (ContrastValue <= ContrastMax) { // Check to make sure is not all the way up already
ContrastValue == ContrastValue - ContrastStep; // Adjust the contrast down by one step
u8g.setContrast(ContrastValue); // Send the new contrast value to the display
}
}
}
// Testing only
void draw() {
// graphic commands to redraw the complete screen should be placed here
u8g.setFont(u8g_font_6x12r);
u8g.drawStr( 0, 15, "6X12r");
// u8g.setFont(u8g_font_6x12Br);
// u8g.drawStr( 63, 15, "6X12Br");
u8g.setFont(u8g_font_9x15r);
u8g.drawStr( 0, 30, "9X15r");
u8g.setFont(u8g_font_9x15Br);
u8g.drawStr( 63, 30, "9X15Br");
u8g.setFont(u8g_font_9x18r);
u8g.drawStr( 0, 50, "9X18r");
u8g.setFont(u8g_font_9x18Br);
u8g.drawStr( 63, 50, "9X18Br");
u8g.setFont(u8g_font_10x20r);
u8g.drawStr( 0, 63, "10X20r");
// u8g.setFont(u8g_font_10x20Br);
// u8g.drawStr( 63, 63, "10X20Br");
}
void loop() {
// picture loop
u8g.firstPage();
do {
draw(); // Testing only
}
while( u8g.nextPage() );
// rebuild the picture after some delay
delay(1000);
SetContrast(); // Screen Contrast Adjustment via push buttons
//DisplayVoltage(); // Display vehicle voltage
//DisplayTemp(); // Display ambient temperature
}