Trouble using serial OLED display (uOLED-96-G1) arduino mega

Im trying to use an OLED display (uOLED-96-G1 http://www.sparkfun.com/products/8538) with an Arduino Mega 2560. The display has a serial interface, and should be able to automatically detect the baud rate.

I have connected:

Display Power → Arduino +5V

Display Ground → Arduino Ground

Display Reset → Arduino Digital Pin 8

Display RX → 100 Ohm resistor → Arduino TX

Display TX → Arduino RX

Nothing else is connected to the Arduino. The Display does not have an SDCard inserted, and there is a “Run” jumper that is not documented in the display’s specifications, but I have tested it with the jumper on and without it.

According to the documentation, the display controller is supposed to be able to automatically detect the serial baud rate. This is done by sending the byte 0x55. The display is then supposed to return an ACK of 0x06 or a failure of 0X15.

When the Arduino starts up, the display turns on. It displays some hardware information about the display itself (the component name and firmware version) for a period of time ranging from 10 seconds to 30 seconds. The display then goes dark and will not come on again until either the Arduino is restarted, or the reset pin is switched from high to low, and then to high again.

In either case, when I try to issue the baud rate detection byte 0x55, the display never responds. The call to read the ACK/NAK byte from the display just blocks forever. I have tried adding delays between various different steps in the process and have still not been able to get past waiting for the response byte.

I’m new to Arduinos, so I’m wondering if there’s something obvious I’m missing here in regards to correct serial communication techniques. For all I know, the 0x55 byte isn’t even making it to the display, so the problem could be either that the Arduino’s transmissions aren’t making it to the display, or the displays transmissions aren’t making it back to the Arduino. I don’t really know how I could test to see which is the case.

I have tested the serial communication to the Arudino serial monitor and that does work. But that doesn’t really tell me much.

The following is a simple sketch I’m trying to get working. Its supposed to just turn on the display and set a pixel at (10, 10) to white.

const long OLED_BAUD_RATE = 57600;
const int OLED_RESET_PIN = 8;

/**
 *	Startup routine
 */
void setup(){
  // Start the log monitor serial port
  Serial.begin(9600);
  
  // Setup the restart pin for the display
  pinMode(OLED_RESET_PIN, OUTPUT);

  // Sleep for 10 seconds
  for (int x = 0; x < 10; x++) {
	  delay(1000);  
	  Serial.print("Sleeping ");
	  Serial.print(x, DEC);
	  Serial.println("");
  }
  
  // Restart the display
  displayRestart();
  delay(4000);
  
  // Initialize the display
  displayInit();
  delay(4000);
}

/**
 *	Restart the OLED display by lowering and raising the reset pin
 */
void displayRestart() {
  Serial.println("Restarting the display");
  delay(10);
  digitalWrite(OLED_RESET_PIN,LOW);
  delay(10);
  digitalWrite(OLED_RESET_PIN,HIGH);
  delay(10);
}

/**
 *	Perform the startup operation as described by the OLED display manual.  This includes
 *	starting a serial connection, sending a byte of 0x55 so the display can detect the baud rate,
 *	can finally, sending the clear screen (0x45) code.
 */
void displayInit() {
  // Begin serial
  Serial.print("Starting serial connection to display (baud ");
  Serial.print(OLED_BAUD_RATE);
  Serial.println(")");
  Serial2.begin(57600);
  
  delay(1000);
  
  // Send baudrate id
  Serial.println("Writing baudrate detection byte to display (0x55)");
  Serial2.write(0x55);
  readSerial(6000);
  
  delay(1000);
  
  // Clear the screen
  Serial.println("Clearing display (0x45)");
  Serial2.write(0x45);
  readSerial(6000);
}

/**
 *	Draw a pixel at (y = 10, x = 10) with a color of white
 */
void loop(){
	Serial.println("Drawing pixel to display (0x50, 0x0A, 0x0A, 0xFFFF)");
	Serial2.write(0x50);
	Serial2.write(0x0A);
	Serial2.write(0x0A);
	Serial2.write(0xFF);
	Serial2.write(0xFF);
	readSerial(6000);
}

/**
 *	Read a single byte from the serial connection with the OLED display
 *
 *	@param timeout the amount of time to try and read the value before giving up (in milliseconds)
 *
 *	@return the value that was read from the serial connection
 */
char readSerial(long timeout) {
  long starttime = millis();
  Serial.print(">> Reading serial... ");
  while (Serial2.available() == 0) { 
    if (millis() - starttime > timeout) {
      Serial.println("<ERROR: Serial Timeout>");
      return 0x15;
    }
  }
  char res = Serial2.read();
  
  Serial.print("(Value: ");
  Serial.print(res, DEC);
  Serial.println(")");
  
  return res;
}

The output from the serial monitor is as follows:

Sleeping 0
Sleeping 1
Sleeping 2
Sleeping 3
Sleeping 4
Sleeping 5
Sleeping 6
Sleeping 7
Sleeping 8
Sleeping 9
Restarting the display
Starting serial connection to display (baud 57600)
Writing baudrate detection byte to display (0x55)
>> Reading serial... <ERROR: Serial Timeout>
Clearing display (0x45)
>> Reading serial... <ERROR: Serial Timeout>
Drawing pixel to display (0x50, 0x0A, 0x0A, 0xFFFF)
>> Reading serial... <ERROR: Serial Timeout>
Drawing pixel to display (0x50, 0x0A, 0x0A, 0xFFFF)
>> Reading serial... <ERROR: Serial Timeout>
Drawing pixel to display (0x50, 0x0A, 0x0A, 0xFFFF)
>> Reading serial... <ERROR: Serial Timeout>

I contacted the manufacturer of the OLED display, and they said there are two different types of firmware that could be pre-loaded on the display controller. Either its the GFX firmware, or the SGC firmware. The difference is explained:

GFX: Firmware designed to handle programs written using the 4dsystems custom IDE and language, and which run directly on the display controller board. If this firmware is installed, the display will start with a splash screen that details the hardware specs in small green text in the upper left corner. The text will display for several seconds (10-30) and will the shutoff. Serial communication with this firmware does not work as described in the specifications.

SGC: Firmware that allows the display to be controlled over serial. If this firmware is installed, the display will start with a colorful splash-screen that scrolls. Serial communication with this firmware works as described in the display documentation.

The version I was shipped, was the GFX, so in order to get the display to work, I had to connect a Serial-to-USB chip directly to the display controller board. Then downloaded the “PmmC” firmware loader from the 4dsystems website, and loaded the SGC PmmC file using the firmware loader. It took a few tries to get the display to accept the firmware. I ended up setting the displays reset pin to HIGH, then starting the firmware load. The app sat idle waiting for a response from the display, so I reset the arduino, which consequently resetting the display. At this point the firmware loader immediately started uploading the data, and completed a few seconds later.

The next time I turned on the OLED display, the colorful splash screen was displayed. After that, all the code I was expecting to work, did its job. There is now a nice diagonal multicolored line on my screen.

  • Note: The undocumented jumper on the display board is used to tell the board to auto-run a slide show that resides on the SD card plugged into the board. For use as a simple serial display, this jumper should be removed.

Thanks for the explanation. Will come in handy for future readers! :slight_smile: