DUE + u8glib + ssd1325 (NHD 12864 OLED) = slow refresh rate :( ---FIXED!---

I recently received a 2.7 inch 128x64 OLED from new haven, it uses the SSD1325 controller and is supported by the u8glib library.

This is a 3.3v display, so most of my arduinos wouldn't work with it without the help of a level shifter. I have a DUE on hand that has been woefully neglected for some moths, so i thought it would be a great opportunity to use it.

Long story short, getting the display up and running was quite painless, the u8glib defines SPI pins that are hardware on most arduino boards, however the DUE has them on a separate dedicated header. This turned out not to be an issue (or so i thought) as i just used the default pins and it worked, ran a few demo sketches and thought everything was fine, until.....

I tried to write code to see how fast the OLED would update, basically i did an analog read and print routine, thats when i noticed how painfully slow the update was, to the point that digits got garbled and looked terrible.

How could this be? the DUE is a fast and powerful beast, why does it seem to choke on a lowly 128x64 OLED?

I am pretty sure it has something to do with not using the hardware SPI, the library is obviously implementing a software spi and i am sure that slows it down a bunch, but is that the only issue?

Does anyone know a way to implement the hardware pins with the u8glib library?

does anyone know if the SPI hardware pins can be declared in the IDE ?( i found no reference to what pin numbers they might be)

is there a better library out there? or possibly one that could be substituted?

has anyone ever tried using one of these displays (or a similar type) in parallel mode (6800 or 8080 interface)?

I would love to use this display as it is well suited for my application, but at its current performance level its pretty useless.

thanks Joe

Hi

Which is the actual U8glib constructor you use? U8glib supports HW SPI with the DUE, but these pins are only available on the ISP header.

Another cause for a slowdown often is to call analog read inside the u8glib "picture loop". Sequence should be: a) read analog value b) store the value in a variable c) execute picture loop, output value from variable

Maybe you can also post your code for further discussion.

Oliver

ill do that as soon as i can, im posting this from my iphone, so makes posing code impossible.

I also saw another possible solution further down in the displays section i want to try.

I am curious about the due hardware spi implementation, i must have missed that one in the long list. I am using the NHD2712864GR constuctor (sorry if thats not exactly the way the constuctor is listed, im on my phone )

/*

HelloWorld.pde

“Hello World!” example code.

Before compiling: Please remove comment from the constructor of the
connected graphics display (see below).

Universal 8bit Graphics Library, http://code.google.com/p/u8glib/

Copyright (c) 2012, olikraus@gmail.com
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list
    of conditions and the following disclaimer.

  • Redistributions in binary form must reproduce the above copyright notice, this
    list of conditions and the following disclaimer in the documentation and/or other
    materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#include “U8glib.h”

U8GLIB_NHD27OLED_GR u8g(3, 4, 5, 6); // SPI Com: SCK = 13, MOSI = 11, CS = 10, A0 = 9
//U8GLIB_NHD27OLED_2X_GR u8g(13, 11, 10, 9); // SPI Com: SCK = 13, MOSI = 11, CS = 10 , A0 = 6

int sensorValue = 0;

void drawanalog(){
//analogReadResolution(12);
sensorValue = analogRead(A0);
u8g.setPrintPos(80, 62);
u8g.print(sensorValue);
}
void setup(void) {
analogReadResolution(12);
// flip screen, if required
// u8g.setRot180();

// set SPI backup if required
//u8g.setHardwareBackup(u8g_backup_avr_spi);
if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) {
u8g.setColorIndex(3);
}
u8g.setFont(u8g_font_unifont);
//u8g.setFont(u8g_font_osb21);
}

void loop(void) {
// picture loop
u8g.firstPage();
do {
//draw();
drawanalog();
} while( u8g.nextPage() );

// rebuild the picture after some delay
delay(50);

}

Here is the quick and dirty code i hacked together, even with the 50ms delay it is not usable.

going to try and get it working on the hardware spi…

Hi

U8GLIB_NHD27OLED_GR u8g(3, 4, 5, 6);   // SPI Com: SCK = 3, MOSI = 4, CS = 5, A0 = 6

HW and SW SPI is selected based on the number or arguments. With the constructor above, you will always select SW SPI. HW SPI is only available at specific Pins of the Due (109 MOSI and 110 clock, if i remember correctly). So you just need to remove the first two arguments and reconnect SCK and MOSI:

U8GLIB_NHD27OLED_GR u8g(5, 6);   // HW SPI, CS = 10, A0 = 9

The other slow down is caused by the fact that the analog read is part of your picture loop: A little bit simplified, your code looks like this:

void loop(void) {
  u8g.firstPage(); 
  do {
    sensorValue = analogRead(A0);
    u8g.setPrintPos(80, 62);
    u8g.print(sensorValue);
  } while( u8g.nextPage() );
}

Instead do this:

void loop(void) {
  sensorValue = analogRead(A0);
  u8g.firstPage(); 
  do {
    u8g.setPrintPos(80, 62);
    u8g.print(sensorValue);
  } while( u8g.nextPage() );
}

Details on the picture loop are given here: https://code.google.com/p/u8glib/wiki/tpictureloop

Additional speedup is possible (but also more RAM will be used) with the 2X constructor.

Hope this helps to solve your performance problems.

Oliver

got the hardware spi working, didn't make much difference.

i must have something terribly wrong, it takes almost a second to render a new digit (i would say ~700-750ms)

Did you pull out the analogRead from the inner loop? But i agree, also with the analogRead inside the loop, it should be much faster.

I have not yet tested Arduino 1.5.6-r2 IDE. Latest tested release is 1.5.5

Oliver

i have got it working, i haven't tried the analog changes yet, but i am satisfied with the results so far, it is very fast now.

Trick was to leave the first two pins SCK and MOSI undefined, so U8GLIB_NHD270LED_2X_GR u8g(pin, pin);

at first i tried to use pin 4 as CS, as it is one of the HW SPI pins, that didn't work very well so I changed it to 10, and BAM!, thng works awesome.

so right now i have it set as: U8GLIB_NHD270LED_2X_GR u8g(10,9). SCK and MOSI pins are 3,4 of the ICSP header respectively and its working great.

Thanks for all your help and your detailed responses, means a lot to a newb like me.

I'll play with the analog read code more tomorrow, but right now i have to call it a night.

thanks again!