Teensy 3.1 and u8glib why so slow?...

Status
Not open for further replies.

joey120373

Well-known member
I have been playing around with arduino pro mini and a teensy 3.1&LC, using the u8glib and an adafruit OLED ( SSD1352 controller if memmory serves me correctly ) .

The oled I am using is the SPI version and I am using hardware SPI.

I was hoping to get more FPS with the teensy, however it appears that the FPS is pretty much the same regardless of which controller I am using. I'm simply running one of the example sketches.

I'm guessing that the reason there is no real speed improvement is that the SPI clock is the same?
Has anyone played around with the U8glib to optimize it for teensy3.x?

Thanks
 
I found that using the Teensy 3.1 to drive an adafruit 128x128 OLED gave much better performance than the Arduino Pro Mini, was a while back and never tried to quantify it. I used the adafruit GFX lib.
 
Last edited:
I found that using the Teensy 3.1 to drive an adafruit 128x128 OLED gave much better performance than the Arduino Pro Mini, was a while back and never tried to quantify it. I used the adafruit GFX lib.

I also played with the adafruit GFX lib several months back, and as i recall it was quite a bit faster on the teensy3.x compared to the mini, I also tested the DUE, I cant remember which was fastest, the DUE or the teensy, both were very fast and i think the difference was negligible.

But I much prefer the fonts available with the U8glib, the "2x" offered by the GFX lib just looks tacky compared to the U8glib larger fonts.
I am getting acceptable performance out of it now, 10-11 FPS, but i would love to double or triple that if i could.
 
I also played with the adafruit GFX lib several months back, and as i recall it was quite a bit faster on the teensy3.x compared to the mini, I also tested the DUE, I cant remember which was fastest, the DUE or the teensy, both were very fast and i think the difference was negligible.

But I much prefer the fonts available with the U8glib, the "2x" offered by the GFX lib just looks tacky compared to the U8glib larger fonts.
I am getting acceptable performance out of it now, 10-11 FPS, but i would love to double or triple that if i could.

Not sure what you're rendering on your display, but here's a couple of ideas, though I have no experience with U8glib

First I don't know if the bottleneck is the Adafruit code or the SPI transfer (presume you're using hardware SPI), I guess it's the CPU from what I've seen. Given this caveat, Adafruit_GFX (via the SSD1306 driver my OLED uses), goes to some lengths to avoid you addressing pixels outside the display, eg drawPixel() which is used heavily, tests your (x,y) coordinate to ensure they're inside the display bounds as well as checking your rotation flag. If you don't need these, you could strip the code to see if it improves things as long as you're careful with clipping etc. You could almost use a debug & release flag to conditionally compile in/out those checks.

In one of my apps, I was displaying lots of text, and this is quite time consuming to render, so I wrote a little utility class that store text strings and their (x,y) coordinates. It would only render a character in the text if it's changed. That made a huge difference to fps (x2 or 3 on an arduino pro mini), eg to GPS lat/long where most digits changed infrequently, though it used up some RAM to do this. I'll post some code in a bit if I can find it, though it may not be too elegant... The crucial thing is not to make the CPU do any more work than is absolutely necessary and use RAM to cache anything you can as there's a fair bit on the Teensy
 
Not sure what you're rendering on your display, but here's a couple of ideas, though I have no experience with U8glib

First I don't know if the bottleneck is the Adafruit code or the SPI transfer (presume you're using hardware SPI), I guess it's the CPU from what I've seen. Given this caveat, Adafruit_GFX (via the SSD1306 driver my OLED uses), goes to some lengths to avoid you addressing pixels outside the display, eg drawPixel() which is used heavily, tests your (x,y) coordinate to ensure they're inside the display bounds as well as checking your rotation flag. If you don't need these, you could strip the code to see if it improves things as long as you're careful with clipping etc. You could almost use a debug & release flag to conditionally compile in/out those checks.

In one of my apps, I was displaying lots of text, and this is quite time consuming to render, so I wrote a little utility class that store text strings and their (x,y) coordinates. It would only render a character in the text if it's changed. That made a huge difference to fps (x2 or 3 on an arduino pro mini), eg to GPS lat/long where most digits changed infrequently, though it used up some RAM to do this. I'll post some code in a bit if I can find it, though it may not be too elegant... The crucial thing is not to make the CPU do any more work than is absolutely necessary and use RAM to cache anything you can as there's a fair bit on the Teensy

Found the code, like I said, it's not pretty, note we don't need to delete[] our text(!) - here's the struct:

struct OledItem
{
OledItem(size_t maxTextLen, int x, int y, int textSize, int fgColour, int bgColour)
: m_text(new char[maxTextLen + 1]),
m_x(x), m_y(y),
m_textSize(textSize),
m_fgColour(fgColour),
m_bgColour(bgColour)
{
*m_text = '\0';
}

void setText(const char* text)
{
const char* p1 = m_text;
const char* p2 = text;

oled.setTextSize(m_textSize);
oled.setTextColor(m_fgColour, m_bgColour);

int x = m_x;

for(;;)
{
if (*p1 != *p2)
{
oled.setCursor(x, m_y);
oled.print(*p2);
}

if (*p1 != '\0') p1++;
if (*p2 != '\0') p2++;

if (*p1 == *p2 && *p1 == '\0') break;

x += m_textSize * 6;
}
strcpy(m_text, text);
}

char* m_text;
int m_x;
int m_y;
int m_textSize;
int m_fgColour;
int m_bgColour;
};

To use it, declare your OledItems:

OledItem oiLatitude(13, 4, 49, 1, GREEN, BLACK);
OledItem oiLongitude(13, 4, 59, 1, GREEN, BLACK);

To update the text, do this:

oiLatitude.setText(formatPrintPosition(GPS.latitudeDegrees, GPS.lat));
oiLongitude.setText(formatPrintPosition(GPS.longitudeDegrees, GPS.lon));
 
wow, thanks. not sure how well that aproach will work with the u8glib, but its worth a shot. my project is a wide band oxygen controller, talking wirelessly via nrf24l to an arduino pro mini/oled. the data displayed is simply the afr, a float.

however i am using a very large font so that it is easily read from several feet away. right now my loop time, reading the data from the radio and writing it to the oled, is just shy of 100 ms, but i also would like to data log to an SD card, my fear is that this will add enough time to the loop as to make the display appear sluggish. the 11ish fps i am getting now is pretty good, but i would love to have more if i can get it.
 
IIRC, u8glib and the adafruit go about things very differently so this is unlikely to just carry over.

i might be wrong on that (happy to be proven wrong in fact), but with u8glib you always have to re-write the full display, you can't just write individual pixels that changed. one thing to try though is to increase the frame buffer size ( https://code.google.com/p/u8glib/wiki/tpictureloop#Local_Frame_Buffer ). needs more RAM, but will/should speed things up somewhat.

that'll be display specific. as it stands, for supported devices you typically have the choice between two different com functions (1x and 2x -- eg u8g_dev_ssd1306_128x64_hw_spi vs u8g_dev_ssd1306_128x64_2x_hw_spi) ; 2x is faster but needs more RAM; in principle, if there's enough RAM to spare, you can try increasing the buffer size. i haven't tried this myself but you'd have to look at the respective device call back and add a suitable callback function; e.g. to double the buffer , i guess you'd add something along the lines of :


uint8_t u8g_dev_ssd1306_128x64_4x_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) {

switch(msg)

// ... etc
}

uint8_t u8g_dev_ssd1306_128x64_4x_buf[WIDTH*4] U8G_NOCOMMON ;


and make the appropriate changes downstream, mostly that'll be about the "page buffer procedure" (the stuff called u8g_dev_xxx_base_fn)
 
That looks prommising, I'll see if I can change the buffer size and do some testing. I'm not concerned with memory as the teensy has more than enough. I also would like to route around in the U8g lib and see if there is any way to speed up the SPI clock. Using the " SPI_SET_CLOCK_DIV_2 " yield a small gain, but I think that is still not taking full advantage of the teensys faster clock.

Thanks for all the help guys.
 
Status
Not open for further replies.
Back
Top