Using the u8glib on the STM32

{33 Comments}

The u8glib is a really nice library to use when you don’t want to mess around with different diplay protocols or drawing routines. It is well-conceived and easy to use. Unfortunately there has been no port for STM32 microcontrollers so I tried to do this.

In the following example I will use the library to display some text on a SSD1306 display via I2C. The controller I use is the STM32F101CBT6 and the IDE will be Atollic True Studio for ARM Lite.

You should start by downloading the u8glib for arm. This is the C version of the library which I will use since you can only compile C code with the Lite version of my IDE.

The next step is to implement the entire project into your code. So I created a new folder and just draged in the „src“ folder from the archive.

Now some low level routines have to be implemented to allow the library to talk to the display device. The following routines have to be created:

  • Delay by n microseconds
  • Delay by 10 microseconds
  • Delay by 1 microsecond
  • Doing a Reset on the display
  • Writing a byte to the display
  • Writing a sequence of bytes to the display
  • Switching from data to command mode or vice versa

To do so we create a new source file called „u8g_arm.c“ and a header file „u8g_arm.h„.

In the header file you should include the original u8g.h header file so basically just do:

The most important procedure in these files will be the one that is called by the u8g library with data to send to the display device. This communication procedure looks like this. I added comments for every important statement. Add it to the file „u8g_arm.c“.

Now just add code to every case of the switch statement. For my communication with I2C it looks like this:

My routines to  write and read data via I2C are basically copied from this nice article. If you want the full code please contact me or write a comment since I don’t want to publish it because of bad style.

Ok so now we have the low level hardware communication set up. Now it is time to really enjoy the amazing u8g library.

To tell u8glib to use our communication function we just have to call it like this.

I hope you noticed that the third parameter to this function is our hardware routine.

That is basically all you have to do. Now you can use all functions of the u8glib. Please remind that you use the C library of the project so you cannot directly copy code from the tutorials.

33 Comments…

 Share your views
  1. Thanks a lot for this tutorial!
    Oliver

  2. thank you very much,from china

  3. Thank you for this tutorial, is there also a possibility to use U8glib with Energia? (Arduino-clone from Texas Instruments)

  4. hi, i try to mod the library to use it with stm32f103 and IAR for ARM but when i try to compile there is this error “ no definition for u8g_InitComFn“ and „no definition for u8g_dev_ssd1351_128x128_hicolor_hw_spi“.
    thanks

    • Hi!

      Maybe you did not include the right files? Make sure you include u8g.h (this is where the missing symbols were defined). Also make sure you downloaded the right library (for ARM) from the u8glib site. You can send me your code for review if you want. If I find anything wrong with the article I will update it.

      • Hi,

        Thank you very much for your wonderful effort. I’m trying to compile u8glib for SSD1325 display on an arm based UDOO board. Being a novice I would be respectfully thankful if I could have your source code so that I can understand better. I appreciate the extreme hard work that you’ve done and the time you’ve spent on this.

        Thank you very much.

      • I am also getting the same error, as Paolo. I have ported this over to NRF51822. I think I am getting linking errors since there is no u8g.c file? Any ideas as to what I can try?

        Thanks,
        -Patrick

      • Hi
        I’m getting the same errorr as Paolo when I try to compile. I’m using Keil version 5.0 and I ported this over to work on the nrf51822. I believe there is some linker issue but I just cant see it.Any advice?
        Thanks
        -Patrick

        • Well when I look through pawels errors I mostly see stuff that is not u8glib related. It looks like he is trying to compile C++ code with a C compiler (for example look at the „bool“ and „class“ keyword errors). You have the exact same output?

  5. Hi,

    Thank you very much for your wonderful effort. I’m trying to compile u8glib for SSD1325 display on an arm based UDOO board. Being a novice I would be respectfully thankful if I could have your source code so that I can understand better. I appreciate the extreme hard work that you’ve done and the time you’ve spent on this.

    Thank you very much.

  6. Hi Ben – thanks for writing this.
    I’d like to implement u8glib on an OpenWrt (AR9331 based Linux) router with SPI (UC1608 based display), if you are familiar with Arduino Yun, I would basically like to use the Linux side of the board directly (without programming the Atmel MCU).

    Any ideas on how to approach this? Or is this not possible…any guidance would be greatly appreciated.

    • Sorry I have no experience on the mentioned platforms. But if you want to use an embedded system the best thing is to get the interface you want to use for the display working at first. Then look around for software you could use…

  7. Hello.
    Prompt possible to unite stm32f4 Discovery and display sst7920 & U8glyb.Connection to use SPI

  8. Hello.
    Thanks for the article.
    I was able to connect to the LCD ST7920 – STM32F4 DISCOVERY (u8glib).
    Details on my blog http://radiomanoff.at.ua/index/stm32f4_discovery_lcd_st7920_u8glib/0-71

  9. Hi Ben Thanks for this

    please send me full code ,i need that for lpc17xx port , hamed.t@live.com

  10. I bought a 4-wire OLED display (heltec).

    For arduino they made a modification in the u8glib : U8G_I2C_OPT_NO_ACK.

    (The device cannot send an ACK)

    I’m new to stm32 and have limited skills.

    I’m trying to adapt your script.

    in the configuration of the stm32
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; //should I put here I2C_ACK_DISABLE ?

    In the code there is this line :
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
    So the master is asking the OLED to confirm (=ack?)

    In the arduino equivalent, they skip the check. Can I do the same by leaving out (checkevent) ?

    ( u8g_i2c_opt & U8G_I2C_OPT_NO_ACK ) { /* do not check for ACK */ } else { status = TW_STATUS; /* check status after sla */ if ( status != TW_MT_SLA_ACK ) { u8g_i2c_set_error(U8G_I2C_ERR_BUS, 2); return 0; }

    Kind Regards,
    Jan

    • Hello, it depends on your device. If it sends ACK, then I think you can ignore the U8G_I2C_OPT_NO_ACK. Which display are you exactly using?

  11. Thank you very much, It is most appreciated.

    Do you think that I can use u8glib with ATOM 64 bit ? Which porting do you think I need to do ?
    I also need to use it with ssd1305 which is not supported yet ?
    We have ssd1305 driver (u8glib does not support it).
    Is using u8glib graphic library for menus/display programming is advisable or I can use plain driver ?
    Do you think I can tailor the driver inside u8glib (so that the lib will use it )?

    Thank you!

  12. Hi! i try to port u8glib to stm32f1 using NEW hal drivers. How you make microseconds delay function? Can you show this function?

  13. Hi!

    I’m trying to apply your solution to my project (STM32F103 and SSD1306 i2c only) but I get weird results. The display works only about 1 out of 2-5 resets. What I see is that the microcontroller stucks into the event checks for i2c. The events I wait for never occur. I tried adding timeouts but then again the whole initialization process is disrupted… Have you encountered this before?

  14. Hi, could you explain in which file exactly I have to be put your code from above to make STM32 with u8glib work? I’ll tryied but can’t compile it.
    I use maple mini 2, I have SSD1306 library for STM32 which is work but would like to run also u8glib as there is plenty of OLED displays 1.3″ with SH1106 driver, which nicely work with AVR’s but not
    with STM, at the moment.
    I’ll made two files u8g_arm.c and u8g_arm.h and put code you described above, but arduinoIDE can’t compile this code.
    Could you explain more step by step which portion of the code shoulde be placed where to make this work?
    I appreciate your help

    • I didn’t work with the Arduino IDE for a long time, but maybe it just does not find your include/header files? You also need to pass your source files to the compiler. Did you use the Arduino style low level routines to access the I2C or did you write them in the ST Standard Periphal style? It should be as simple as creating a c and header file having the given structure, implementing the low level routines and passing them to the u8g lib.

      Or do you have any specific compile error?

      • Hi, I have this error info

        In file included from /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/wirish.h:52:0,
        from /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/Arduino.h:30,
        from /home/pawel/Pobrane/arduino-1.6.1/libraries/U8glib/utility/u8g_com_arduino_common.c:46:
        /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/boards.h:111:1: error: unknown type name ‚bool‘
        bool boardUsesPin(uint8 pin);
        ^
        In file included from /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/wirish.h:53:0,
        from /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/Arduino.h:30,
        from /home/pawel/Pobrane/arduino-1.6.1/libraries/U8glib/utility/u8g_com_arduino_common.c:46:
        /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/io.h:184:32: error: expected ‚;‘, ‚,‘ or ‚)‘ before ‚=‘ token
        uint8 isButtonPressed(uint8 pin=BOARD_BUTTON_PIN,
        ^
        /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/io.h:204:47: error: expected ‚;‘, ‚,‘ or ‚)‘ before ‚=‘ token
        uint8 waitForButtonPress(uint32 timeout_millis=0);
        ^
        In file included from /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/wirish.h:56:0,
        from /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/Arduino.h:30,
        from /home/pawel/Pobrane/arduino-1.6.1/libraries/U8glib/utility/u8g_com_arduino_common.c:46:
        /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/ext_interrupts.h:90:6: error: conflicting types for ‚attachInterrupt‘
        void attachInterrupt(uint8 pin, voidArgumentFuncPtr handler, void *arg,
        ^
        /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/ext_interrupts.h:69:6: note: previous declaration of ‚attachInterrupt‘ was here
        void attachInterrupt(uint8 pin, voidFuncPtr handler, ExtIntTriggerMode mode);
        ^
        In file included from /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/wirish.h:58:0,
        from /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/Arduino.h:30,
        from /home/pawel/Pobrane/arduino-1.6.1/libraries/U8glib/utility/u8g_com_arduino_common.c:46:
        /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/wirish_math.h:58:6: error: conflicting types for ‚random‘
        long random(long min, long max);
        ^
        /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/wirish_math.h:49:6: note: previous declaration of ‚random‘ was here
        long random(long max);
        ^
        In file included from /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/HardwareSerial.h:38:0,
        from /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/wirish.h:66,
        from /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/Arduino.h:30,
        from /home/pawel/Pobrane/arduino-1.6.1/libraries/U8glib/utility/u8g_com_arduino_common.c:46:
        /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/Print.h:37:1: error: unknown type name ‚class‘
        class Print {
        ^
        /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/Print.h:37:13: error: expected ‚=‘, ‚,‘, ‚;‘, ‚asm‘ or ‚__attribute__‘ before ‚{‚ token
        class Print {
        ^
        In file included from /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/HardwareSerial.h:40:0,
        from /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/wirish.h:66,
        from /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/Arduino.h:30,
        from /home/pawel/Pobrane/arduino-1.6.1/libraries/U8glib/utility/u8g_com_arduino_common.c:46:
        /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/Stream.h:38:1: error: unknown type name ‚class‘
        class Stream : public Print
        ^
        /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/Stream.h:38:14: error: expected ‚=‘, ‚,‘, ‚;‘, ‚asm‘ or ‚__attribute__‘ before ‚:‘ token
        class Stream : public Print
        ^
        In file included from /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/wirish.h:66:0,
        from /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/Arduino.h:30,
        from /home/pawel/Pobrane/arduino-1.6.1/libraries/U8glib/utility/u8g_com_arduino_common.c:46:
        /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/HardwareSerial.h:83:1: error: unknown type name ‚class‘
        class HardwareSerial : public Stream {
        ^
        /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/HardwareSerial.h:83:22: error: expected ‚=‘, ‚,‘, ‚;‘, ‚asm‘ or ‚__attribute__‘ before ‚:‘ token
        class HardwareSerial : public Stream {
        ^
        /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/HardwareSerial.h:143:2: error: unknown type name ‚HardwareSerial‘
        extern HardwareSerial Serial1;
        ^
        /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/HardwareSerial.h:146:2: error: unknown type name ‚HardwareSerial‘
        extern HardwareSerial Serial2;
        ^
        /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/HardwareSerial.h:149:2: error: unknown type name ‚HardwareSerial‘
        extern HardwareSerial Serial3;
        ^
        In file included from /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/wirish.h:67:0,
        from /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/Arduino.h:30,
        from /home/pawel/Pobrane/arduino-1.6.1/libraries/U8glib/utility/u8g_com_arduino_common.c:46:
        /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/HardwareTimer.h:44:1: error: unknown type name ‚class‘
        class HardwareTimer {
        ^
        /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/HardwareTimer.h:44:21: error: expected ‚=‘, ‚,‘, ‚;‘, ‚asm‘ or ‚__attribute__‘ before ‚{‚ token
        class HardwareTimer {
        ^
        /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/HardwareTimer.h:303:1: error: unknown type name ‚HardwareTimer‘
        extern HardwareTimer Timer1;
        ^
        /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/HardwareTimer.h:309:1: error: unknown type name ‚HardwareTimer‘
        extern HardwareTimer Timer2;
        ^
        /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/HardwareTimer.h:315:1: error: unknown type name ‚HardwareTimer‘
        extern HardwareTimer Timer3;
        ^
        /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/HardwareTimer.h:321:1: error: unknown type name ‚HardwareTimer‘
        extern HardwareTimer Timer4;
        ^
        In file included from /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/wirish.h:68:0,
        from /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/Arduino.h:30,
        from /home/pawel/Pobrane/arduino-1.6.1/libraries/U8glib/utility/u8g_com_arduino_common.c:46:
        /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/usb_serial.h:41:1: error: unknown type name ‚class‘
        class USBSerial : public Stream {
        ^
        /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/usb_serial.h:41:17: error: expected ‚=‘, ‚,‘, ‚;‘, ‚asm‘ or ‚__attribute__‘ before ‚:‘ token
        class USBSerial : public Stream {
        ^
        In file included from /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/wirish.h:68:0,
        from /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/Arduino.h:30,
        from /home/pawel/Pobrane/arduino-1.6.1/libraries/U8glib/utility/u8g_com_arduino_common.c:46:
        /home/pawel/Pobrane/arduino-1.6.1/hardware/Arduino_STM32/STM32F1XX/cores/maple/usb_serial.h:79:2: error: unknown type name ‚USBSerial‘
        extern USBSerial Serial;
        ^
        Compilation Error.

  15. Wow awesome, I can’t wait to try this. Thanks so much for putting this together.

  16. Has anyone tried to use m2tklib on top of that with STM32F4?

  17. While trying to compile this I get an error

    Error[Pe144]: a value of type „uint8_t (*)(void *, void *, uint8_t, void *)“ cannot be used to initialize an entity of type „u8g_dev_fnptr“ …\u8glib\src\u8g_rot.c 48

    Does anybody know how to solve this? Thanks!

Leave a Comment

Your email address will not be published.


Time limit is exhausted. Please reload CAPTCHA.

{ 1 Trackback }

  1. STM32 HAL driver for I2C OLED display with U8glib | Wojciech Domski Blog (Pingback)