ESP8266, NodeMCU: how to create xbm images for displaying on OLED 128×64 I2C Displays

Do you know these wonderfully cheap SSD1306 based OLED displays with the crispy display? For a while now the NodeMCU Lua firmware for the ESP8266 supports them and has a rich feature set to draw lines, circles and even bitmaps.
One way to draw bitmaps is in the XBM format, which is originally a text based format and they can be directly included into C code:

#define clouds_width 60
#define clouds_height 60
static unsigned short clouds_bits[] = {
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
   ...
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
   0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };

When looking at the examples on the NodeMCU Github page the xbm file looks a bit different:

fff ffff 3fff ffff ff3f e0e0 ffff 3fe3
e1ff ff3f f3f1 ffff 3ff3 f1fe bf37 f311
1c1f 30f3 0108 8c20 f301 00c0 39f3 81c7
c139 f3c1 c7c9 38f3 c1c3 193c e389 0198
3fc7 1800 083e 0f3c 701c 303f fffc 8731
ffff bfc7 2301 0000 c623 0300 000e 30ff
ff3f 1f3c ffff 3fff 3fff ff3f ff3f ffff
ffff 3fff ffff ff3f 

[the_ad_placement id=”inpostplacement”]

So how to you get your images in the right format? The NodeMCU Api documentation for drawXBM gives a good hint, but I had to apply a minor tweak which turns out to simplify things further:

  • Go to: http://www.online-utility.org/image_converter.jsp
  • Select MONO aus Output format AND press “Select format” (Who has invented THAT UI???)
  • Upload your image. I was succesful with a monochrome PNG file, whereas the XBM only resulted in an error.
  • Upload the created MONO file to your ESP8266 and use it with a code like this:
-- setup I2c and connect display
function init_i2c_display()
     -- SDA and SCL can be assigned freely to available GPIOs
     sda = 5 -- GPIO14
     scl = 6 -- GPIO12
     sla = 0x3c
     i2c.setup(0, sda, scl, i2c.SLOW)
     disp = u8g.ssd1306_128x64_i2c(sla)
end

function xbm_picture()
     disp:setFont(u8g.font_6x10)
     disp:drawStr( 0, 62, "Rainy   8C")
     disp:drawXBM( 0, -5, 60, 60, xbm_data )
end

function bitmap_test(delay)
     file.open("clouds.xbm", "r")
     xbm_data = file.read()
     file.close()

      disp:firstPage()
      repeat
           xbm_picture()
      until disp:nextPage() == false

      tmr.wdclr()
end

init_i2c_display()
bitmap_test()
SSD1306 OLED 128×64 display,
connected to a NodeMCU DevKit V1.0
You just need to connect four pins of the display

to the NodeMCU

Update 11 June 2015 – Batch Processing

In case you have many images to convert to xbm you might consider installing imagemagick and do it with a few lines on the command line. This example assumes that you want to resize your source png’s into xbm format of 60×60:
mogrify -resize 60x60 +dither -format xbm *.png
cat *.xbm | sed s/static/const/ | sed s/=/PROGMEM=/  > icons.h
You will still need to do a bit of hand processing, for instance adding the PROGMEM command, so the images can be handled more efficiently.

Source

Shopping Links:

 

Posted by Daniel Eichhorn

Daniel Eichhorn is a software engineer and an enthusiastic maker. He loves working on projects related to the Internet of Things, electronics, and embedded software. He owns two 3D printers: a Creality Ender 3 V2 and an Elegoo Mars 3. In 2018, he co-founded ThingPulse along with Marcel Stör. Together, they develop IoT hardware and distribute it to various locations around the world.

6 comments

  1. Great project! I'm new to using NodeMCU and would like to try your example: simple-oled-example. Do I install the latest NodeMCU version: nodemcu_float_0.9.6-dev_20150406.bin

    The latest ESplorer and upload all the files. clouds.png, clouds.xbm, displayXBM.lua, simple-oled-sketch.fzz, simple-oled-sketch_bb.png to the ESP?

    I'm not sure what to do then? I see a compile and run button.

  2. Best way I found so far is to use GIMP for creating the XBM image formats.
    I had limited results using Graphics Magick specially during re-scale where the pixels where just not right…

Leave a Reply