U8glib: Graphics Lib for LCDs and OLEDs

Many thanks to DooMMasteR for the contributed fixes and the new font.

The font update applies to this font:
http://code.google.com/p/u8glib/wiki/fontgroupfreeuniversal

The new font is described here:
http://code.google.com/p/u8glib/wiki/fontgroupcontributed

I have also added some more fonts from the X11 distribution. Some nice large bitmap fonts are also included:
http://code.google.com/p/u8glib/wiki/fontgroupadobex11

I have attached u8glib version v1.09pre14, which includes all these fonts.

Oliver

u8glib_arduino_v1.09pre14.zip (952 KB)

nice :slight_smile: thx a lot

I will also make another font… in 10px height…maybe even today

EDIT: done
numerics, capitals, degree, math included… 10px high 7-8 wide
http://uschok.de/~doommaster/freedoomr10r.bdf

I'm really stoked you guys are doing this! I took a look and was a little intimidated by the process of making my own font and converting it, as I know almost nothing about fonts. (Also FontForge crashes on my computer.)

Thank you!

@DooMMasteR

Great, thanks for the contribution (Karma+)

I have added your font to the distribution: Google Code Archive - Long-term storage for Google Code Project Hosting.

Oliver

@koyaanisqatsi

I usually only use Linux software here (like FontForge). For Windows also "Fony" might work.

Oliver

koyaanisqatsi:
I took a look and was a little intimidated by the process of making my own font and converting it, as I know almost nothing about fonts. (Also FontForge crashes on my computer.)

Thank you!

FontForge is definitely the way to go… but I am also a bit noobish in using it.
I cannot for example, get into bitmap mode from an empty font… I have to import another existing bitmapfont and work from there on -.- which is kind of annoying… but it works.

If you have it in bitmap mode… it is VERY easy to create a pixel perfect bitmap font

I am using a selfcompiled version of FontForge on MacOS X

@olikraus
the new fonts are also copyleft :slight_smile: (public domain) as the other too… I think that I will never do a copyrighted/limited/unfree font :stuck_out_tongue:

HA HA, I have prevailed! FontForge is now running in Ubuntu in a VM (the version available in Ubuntu is kinda old, but it works fine so far). And I think I might be getting the hang of this.

I found how to make bitmap fonts from a new/empty font:

  • Start a new font
  • Element -> Bitmap Strikes Available...
  • Choose "X" and specify a pixel size (height)
  • When you edit a glyph, it should edit in bitmap mode. If not, then Window -> New Bitmap Window, and then close/minimize the outline window.

Will be trying out dbf2u8g.exe in the next few days.

Now if only I had an idea on how I want the font to look... :roll_eyes:

nice…
I have updated the Numerics font, since the 1 was made non monospaced…
http://uschok.de/~doommaster/freedoomr25n.bdf

I pushed my wor to gihub, including my started PCB/schematics

I am still struggling with the license I should use… U8Glib is BSD style… so basically anything is fine… but the DallasTemperature library is LGPL and I do not know in what aspects that is limiting my options :stuck_out_tongue: ahhrg LicenseWars :stuck_out_tongue:

This is my personal interpreation about the difference between LGPL and BSD License:
LGPL is more strict and requires that the user can rebuild the complete project which makes use of the LGPL Software. It must be possible to rebuild the complete project with an updated version of the LGPL part. In the case where your complete software is available on github or similar platforms, than this difference does not matter.

However you need to inform the user about the different parts and licenses of your software.

For example, have a look at the u8glib license: Google Code Archive - Long-term storage for Google Code Project Hosting.
U8glib does not have a single license. Each font might have a different license with different requirerments.
Depending on the font, which are used in your project, you might need to give proper reference.

Oliver

New release available for download: U8glib v1.09

http://code.google.com/p/u8glib/downloads/list

  • Verified with Arduino 1.0.3
  • Fixes several issues with the ST7920 controller
  • Additional fonts
  • Box and frame with round edges: u8g::drawRBox(), u8g::drawRFrame()
  • Support for more displays and communication interfaces

Thanks for all the input and contributions!

Oliver

I downloaded this library a couple days ago and am having a blast with it! It is the most comprehensive and flexible display library I've seen.

However, I'm having a bit of trouble doing some simple stuff.

I'm basically trying to get my screen to plot the input of the ADC; a line over time, sort of like the way an oscilloscope scans when the time/div is big enough. Or how an EKG display refreshes (which is what my application is.) I was previously doing this with a generic parallel GLCD using the GLCD library. Here's how I was doing it:

#include <glcd.h>

int xPos = 0; // X position value.
int pot; // Potentiometer value.

void setup()
{
  GLCD.Init();
  GLCD.ClearScreen();
}

void  loop()
{  
  for(xPos = 0; xPos < 127; xPos += 1) 
  {                               
    pot = analogRead(A0); // Sample ADC
    pot = map(pot, 0, 1023, 0, 63); // Scale down readings to LCD's vertical pixel count.
    GLCD.DrawVLine(xPos, 0, 63, WHITE); // Erase column of pixels previously set.
    GLCD.SetDot(xPos, pot, BLACK); // Set new pixel.
    delay(10);
  } // End FOR statement.

  if(xPos == 127)
  {
    xPos = 0; // Return to the first column when the last column is reached. 
  } // End IF statement.

} // End void loop()

I changed this to fit the profile of this library by doing away with the For loop and fitting it in a Do While, changing the functions, so on. (I'd post it, but it appears that I didn't save it :~ ) It of course doesn't work since this library (to my understanding) rewrites the entire screen each time it cycles rather than just the pixels specified in the functions. Instead, it just scans a single pixel.

I guess what I'm asking is for some insight on how I might be able to get this library to continuously draw without necessarily rewriting the entire display, if that's possible in the first place.

If I must rewrite the full display, I guess I could store all 128 columns in an array and write them all over every time I refresh. I'm not sure how efficient that is, though.

Cheers,

  • Muhammad.

If I must rewrite the full display, I guess I could store all 128 columns in an array and write them all over every time I refresh. I'm not sure how efficient that is, though.

This is correct. You must store the 128 values in order to be able to refresh the display. It is indeed the key difference between u8glib and GLCDv3. For sure this makes u8glib slower than GLCDv3, but this enables u8glib to support displays where the display frame buffer can not be read back from the display (and still avoid a local full frame buffer).

Oliver

First, thanks for this great library!
I just tested a LM096-128064 (128x64 OLED; SSD1306) with a atmega168 and it works flawless.

Is there a chance, that in a future version, the picture loop philosophy can be activated / deactivated for drawing graphs.
I am facing the same problem as Muhammad in the last posting.

Best regards Roman

Hi Roman

Background:
There are GLCDs were the internal frame buffer (display memory) can not be read by the microcontroller.
This is usually true for displays with SPI interface.

Solutions:

  1. Reserve memory in the microcontroller, render the picture into it and transfer the memory from the microcontroller to the display.
    Disadvantage: Large SRAM consumtion, possible only if display frame buffer size is smaller than the available SRAM.
  2. Reserve some smaller amount of memory (e.g. 1/4 of the display frame buffer size) and render the picture more often (e.g. 4x). This trades time vs. SRAM
    Disadvantage: Slower frame rate, picture loop (more complex API)

U8glib was designed to support displays without read back ability.
U8glib follows solution 2)
U8glib is one of the view libs which support large SPI displays on small (ATTINY) controllers (with very limited SRAM).

A graphics lib such as GLCDv3 for KS0108 controller has a much more convinient programming interface. But GLCDv3 also depends on the fact that it can read memory from the display frame buffer.

U8glib offers a solution for displays not support by other graphics librarys.
U8glib sometimes is the only available lib.
U8glib might be a bad choice in other cases (like using it for KS0108 based displays)

I am glad to hear about success stories with U8glib and i am sorry to offer programming API, which is more complicated and difficult to understand.
I tried to compensate this with many features, a good collection of fonts, reliable functions and a documentation with many pictures.
I am always open to improvements, but i probably can not change its basic feature.

I also suggest to read Bill's remarks on GLCDv3 and u8glib:

More Information:
http://code.google.com/p/u8glib/wiki/tpictureloop

Thanks for your picture,
Oliver

olikraus:
A graphics lib such as GLCDv3 for KS0108 controller has a much more convinient programming interface. But GLCDv3 also depends on the fact that it can read memory from the display frame buffer.

GLCD also has a write-through cache option which creates a frame buffer that it uses for reads
instead of reading the data from glcd memory which can speed up display updates at the expense
of using additional memory.
Turning on the write-through cache also allows GLCD to work the same on write-only displays at the expense of the
memory for the frame buffer. I've thought about creating a shift register interface that could reduce
the number of pins down to 2-3 pins but have never gotten around to it.

Maybe there are some optimizations that could be done to speed up u8glib or offer more capabilities.

For a little speed:

  • maybe provide hints to the low level PAGE_NEXT function as to which area(s) are "dirty" and need updating.
    It could be as simple as a low and high value that indicates the starting page and ending page
    that needs to be pushed to the display.
    Or it could be as complex as a bitmap indicating which bytes have pixel data to be flushed out.
    The low level code could choose to ignore the hints but smarter lower level update routines could
    choose to take advantage of it to reduce updates.
    Seems like the simple low/high hints would be pretty easy to implement and might offer some
    significant speed improvements in certain situations.

  • Could it treat the page buffer as a write through cache instead?
    Seems like a pretty big change but that would allow only writing the modified pages to the display.

Form some additional functionality:

  • Could it create a full frame buffer to provide additional functionality?
    Without write-through, it seems like it wouldn't be that difficult to wedge in.
    The code could use all the same mechanisms it does now, so none of the lower interface code
    has to change. The difference being it would simply always have the rows of data always available.
    The flush code could call the PAGE_NEXT (flush) routines as necessary for each row in the frame buffer
    to update the physical display.
    This would allow for the possibility for things like scrolling or graphic updates on top of existing pixels.

It's always a tradeoff. Some strategies work better than others depending on the nature
of the display updates being done.

--- bill

  • maybe provide hints to the low level PAGE_NEXT function as to which area(s) are "dirty" and need updating.

After the first iteration, it could be known which pages are written. So, empty pages could be skipped. But instead of copying the page to the display, the page needs still to be cleared.

  • Could it treat the page buffer as a write through cache instead?

not exactly sure what you mean about this.

  • Could it create a full frame buffer to provide additional functionality?

Sure, this could be done (as long as there is enough SRAM)

Oliver

After some late-night tinkering, I managed to get it to scan. I guess it just took me some time to get acquainted with the Do While structure of execution. It renders a tad slow, but it's still pretty good. I might have an idea on how to speed things up...

I'm using an LCD I bought off of Ebay, similarly found here: http://tinyurl.com/cxujsag which works perfectly under NHD_C12864.

I can definitely understand the memory oriented design of this library. A lot of display libraries don't fare well on the ATMega168. I know Adafruit's library for the Nokia 5110 display will only work on a 328 and up.

I've attached a photo of it plotting a .4Hz signal from a function generator. I've also attached the program for whoever may be interested in it. Ideas on optimization would be much appreciated :slight_smile:

I really appreciate the work you've put into this library!

  • Muhammad.

SPI_Scan_Test.ino (1.64 KB)

Hi Muhammad
Thanks for sharing your project, however, the code is not readable (downloadable) at least for me.

Oliver