U8glib: Graphics Lib for LCDs and OLEDs

Hi Oliver

Works fine with the adafruit libs. I'm using D2,3 & 4 (Rst)

Tx for the link

Unfortunately i do not have the Adafruit displays for testing.
Some people reported that u8glib will work with a different setup sequence (line 178 of u8g_dev_ssd1306_128x64.c)
You could modify the code to check if (for example) sequence 2 works better.

Oliver

Tx Oliver. I'll try that and revert

May I know how to draw text only on a small region of the LCD without the previously drawn text being wiped out?

I try to put one draw in setup() and another draw in loop(), however what was drawn during setup was all wiped out during loop().

Yes, whenever you use the "picture loop", any previous picture is overwritten. U8glib behaves somehow different to other librieres, but it does only require a small amount of memory.
To solve this problem, add your graphics primitives from the setup procedure to your draw procedure in loop().

For more information on this, please see here: Google Code Archive - Long-term storage for Google Code Project Hosting.

Oliver

Thanks Oliver. I see. It is indeed different with other display libraries where you need to purposely clear the screen.

Hi

Today, I have released v1.16 of U8glib (Google Code Archive - Long-term storage for Google Code Project Hosting.). Changes include:

  • Added support for LD7032 60x32 OLED
  • Added support for SSD1306 OLED, which does not send I2C ACK (issue 239)
  • Added support for SH1106 128x64 OLED
  • Added support for T6963 128x128 displays
  • Added U8GLIB_SSD1306_ADAFRUIT_128X64 constructor

The picture below shows a 0.5" OLED module based on the LD7032 controller (from
here):

Oliver

How do you use the P version of functions like getStrWidthP? The normal way used with things like strncpy_P(dest, PSTR("SOURCE"), size) doesn't seem to work. I get an error when I try it...

invalid conversion from 'const char*' to 'u8g_pgm_uint8_t* {aka unsigned char*}' [-fpermissive]

const char szLabel[] PROGMEM = "Max:";  // defined in global space

u8g.getStrWidthP(szLabel); // Inside a function

Hi

Without having this tested, i think the warning can be ignored.

const char szLabel[] PROGMEM = "Max:";  // defined in global space

u8g.getStrWidthP((unsigned char *)szLabel); // Inside a function

Just thought I'd say thank you for this library. I have used it to get some ebay 1.6 inch 128x64 yellow/green oleds up and running with no hassle at all, what an amazing feat.

These displays are all over ebay at the moment, the top 16 rows are yellow, the rest are green and if you can use that in your application they look pretty great.

My config is:

U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NO_ACK);

void setup ()  {
  
//oled
uint8_t setmode = 1; //set to BW mode
u8g.setColorIndex(1); //Set colour to "white"

...for anyone "googling" out there how to get started with a 1.6" ebay yellow-green OLED display and arduino.

A quick question however:

Do you have any tips on how to slim down the program memory footprint? I am only using a single small font, and a few 'primitives' - basically print and scale2x2. As far as I know, the complier/linker SHOULD only use stuff that is called, but I have a suspicion more is tacked on, used or not when it comes to libraries... thoughts? Otherwise I am going to just make a copy of the library and just try the slash, burn and see method :slight_smile:

Cheers and thanks again,

Jacob

askjacob:
I have a suspicion more is tacked on, used or not when it comes to libraries... thoughts? Otherwise I am going to just make a copy of the library and just try the slash, burn and see method :slight_smile:

Before running off and spending time on a hunch, why not just take a look and
actually see where all the space is going?
Create a listing file from the linked image and you will see all the code generated
and linked in.
That will tell you exactly what is being linked in and how big things are.

--- bill

I have, and there is a large chunk there. A lot of stuff in the code is, for example dedicated to constructors for devices that may or may not be invoked during run-time - not compile time, so I think I can save a fair bit of space if I trim it to the bone.

Or, end up with a non-functioning library as I sever a vital organ. Hence asking the author for his thoughts as I head in.

Cheers
Jacob

askjacob:
I have, and there is a large chunk there. A lot of stuff in the code is, for example dedicated to constructors for devices that may or may not be invoked during run-time - not compile time, so I think I can save a fair bit of space if I trim it to the bone.

Or, end up with a non-functioning library as I sever a vital organ. Hence asking the author for his thoughts as I head in.

Cheers
Jacob

So you created a listing file from the .elf file and actually saw dead code that isn't called and constructor code
for other devices in the linked image?

When I built the "HelloWorld" example for the i2c SD1306 128x64 module for a UNO board,
I only saw the routine for the one expected constructor and not any others.

I'm curious what you saw.

--- bill

Yes, the listing file would be nice to see.
Depending on the fonts U8glib requires about 10K. If you do not need ASCII chars with code higher than 127, then fonts with a "r" postfix can be used to reduce flash memory.
Also other libraries and the use of floating point are common reasons for increased memory usage.

Oliver

Hi Oliver.

First of all, this was not ever intended as any kind of critique on your library - but more on the lack of control and visibility on what the Arduino IDE gives on it's handling of libraries and compiling.

I have found inconsistent results with certain individual libraries with what is done - trimming out unused classes and functions can "greatly" reduce the final build, slightly reduce it, or not at all. Additionally moving code from a library into the main codebase can sometimes also reduce the overhead. Keep in mind here, I am talking about a handful of bytes here and there, not huge amounts all over the place. It all adds up though, when you are at the limit. Same with SRAM.

My thoughts here: this can hard to quantify and test easily, and often does not show up until your program is complex enough possibly edge case the compiler and optimizer, at whatever configuration the Arduino IDE uses.

Perhaps I am outgrowing the Arduino IDE. The hardware platform is nice, and the ability to ignore the 'arduino bits' when you want to is nice too.

Here is the thing though:

1 - Thanks Oliver for the great library. It has saved me much energy and head scratching, and allowed me to provide a neat UI to my project
2 - Thanks for the suffix "r" tip - that alone gave me 4K headroom to play with - much more breathing space and now development time rather than needing to start chopping around inside libraries :slight_smile:

I'm glad I asked in here :slight_smile:

PS does anyone have any good win32/win64 elf listers? I cannot find anything that has been developed beyind say 2009/2010 and they all crash post list generation, making anylsis/comparison between compiles very HARD!

Cheers
Jacob

Without looking at the actual final linked image to see everything and
what is linked in you are dancing in the dark.

Previously you said you did this, but now it sounds like you haven't.

The gcc tool set comes with a set of binutils. There is a tool "objdump" to look at .elf files
The avr-gcc tool package that comes with the IDE comes with the gcc binutils.
In that package, objdump is called "avr-objdump"
I recommend using that with the -S and -h options.

--- bill

bperrybap:
Without looking at the actual final linked image to see everything and
what is linked in you are dancing in the dark.

Previously you said you did this, but now it sounds like you haven't.

--- bill

I have been 'doing it' , but the best I could get using was T34 - however it would crash out post-parsing so I had to work with what was visible with the crash dialogue box open (it didn't cover the output) but I could not screengrab it to compare. The machine I am using is a corporate device where I have been given a sandbox area to play in, however it is still restricted somewhat and does seem to make a lot of apps misbehave, especially since we had some GPO's pushed to minimise the impact of the crytpobit type of viruses (limits execution locations etc).

I will grab the gcc toolchain and give it a shot.

Thanks for that!

Jacob

askjacob:
I will grab the gcc toolchain and give it a shot.
Jacob

If you are using the IDE, then you already have everything you need
as the IDE comes with the avr-gcc tools and the avr version of gnu binutils.
--- bill

olikraus:
Yes, the listing file would be nice to see.
Depending on the fonts U8glib requires about 10K. If you do not need ASCII chars with code higher than 127, then fonts with a "r" postfix can be used to reduce flash memory.
Also other libraries and the use of floating point are common reasons for increased memory usage.

Oliver

Thanks for this awesome piece o' advice in reducing consumed memory. But how do I exactly implement it to my code? I'm intending to use my Attiny85 controlling a SSD1306 and I really don't know where to begin..... =(

Atvaark:
Hi Oliver,

I managed to add support for Arduino ATtiny85 hardware SPI. I tested it with an SSD1306 OLED controller (Adafruit 128x32) and it seems to be working OK. As predicted, it spares some CPU time and program memory.

The mod is attached. Feel free to include it into future releases, as is or modified.

Part of the credit goes to Nick Gammon, thanks to the code he posted there: Faking SPI with Attiny85 - Programming Questions - Arduino Forum

Danke schön for your library. :slight_smile:

Please, would you tell me how did you manage to do it? I'm pretty noob at these advanced issues. I have downloaded your zip file but I don't know where to put the files. Could you please make a little "tutorial" on how to use u8glib with the ATtiny85? I'm using an Arduino Nano as ISP.