U8GLIB and bitmap creation/display

Hello!

I've succesfully setup a ST7920 using the u8glib library. Now I would like to display a small image. The bitmap.pde example taken from the library works well. It draws a little castle, like this:

I've found this software that should allow me to convert an image to hex:

Start with an example, the file in attach is a small png in monochrome.

This, imported in the software, converted to hex, gives me as result:

0x0,0x0,0x0,0x0,0x7e,0x0,0x0,0x0,0x0,0x1,0xff,0xc0,0x0,0x0,0x0,0x7,0xff,0xe0,0x0,0x0,0x0,0xf,0xff,0xf0,0x0,0x0,0x0,0x1f,0xff,0xf8,0x0,0x0,0x0,0x3f,0xc3,0xfc,0x0,0x0,0x0,0x7f,0x0,0xfe,0x0,0x0,0x0,0x7e,0x0,0x7e,
0x0,0x0,0x0,0x7c,0x0,0x3e,0x0,0x0,0x0,0xfc,0x0,0x1f,0x0,0x0,0x0,0xf8,0x0,0x1f,0x7f,0xff,0xff,0xff,0xf0,0x1f,0xff,0xff,0xff,0xff,0xf8,0x1f,0xff,0xff,0xff,0xff,0xf8,0x1f,0x7f,0xff,0xff,0xff,0xf0,0x1f,0x3f,0xff,0xff,0xff,0xe0,0x3e,
0x1f,0xff,0xff,0xff,0xc0,0x7e,0xf,0xff,0xff,0xff,0x80,0xfe,0x7,0xff,0xff,0xff,0xc3,0xfc,0x3,0xff,0xff,0xff,0xff,0xf8,0x1,0xff,0xff,0xff,0xff,0xf0,0x0,0xff,0xff,0xff,0xff,0xe0,0x0,0x7f,0xff,0xf3,0xff,0xc0,0x0,0x3f,0xff,0xe0,0x7e,0x0,
0x0,0x1f,0xff,0xc0,0x0,0x0,0x0,0xf,0xff,0x80,0x0,0x0,0x0,0x7,0xff,0x0,0x0,0x0,0x0,0x3,0xfe,0x0,0x0,0x0,0x0,0x3,0xfe,0x0,0x0,0x0,0x0,0x1,0xfc,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,0x0,
0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,0x0,
0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x1,0xfc,0x0,0x0,0x0,0x1,0xff,0xff,0xfc,0x0,0x0,0x3,0xff,0xff,0xfe,0x0,0x0,0x3,0xff,0xff,0xfe,0x0,0x0,0x3,0xff,0xff,0xfe,0x0,0x0,0x1,0xff,0xff,0xfc,0x0,0x0

And here the complete skatch I'm using, starting from the 'bitmap.pde' example contained in the library:

#include "U8glib.h"

U8GLIB_ST7920_128X64 u8g(7, 6, 5, U8G_PIN_NONE);

const uint8_t cocktail[] PROGMEM = {
  
0x0,0x0,0x0,0x0,0x7e,0x0,0x0,0x0,0x0,0x1,0xff,0xc0,0x0,0x0,0x0,0x7,0xff,0xe0,0x0,0x0,0x0,0xf,0xff,0xf0,0x0,0x0,0x0,0x1f,0xff,0xf8,0x0,0x0,0x0,0x3f,0xc3,0xfc,0x0,0x0,0x0,0x7f,0x0,0xfe,0x0,0x0,0x0,0x7e,0x0,0x7e,
0x0,0x0,0x0,0x7c,0x0,0x3e,0x0,0x0,0x0,0xfc,0x0,0x1f,0x0,0x0,0x0,0xf8,0x0,0x1f,0x7f,0xff,0xff,0xff,0xf0,0x1f,0xff,0xff,0xff,0xff,0xf8,0x1f,0xff,0xff,0xff,0xff,0xf8,0x1f,0x7f,0xff,0xff,0xff,0xf0,0x1f,0x3f,0xff,0xff,0xff,0xe0,0x3e,
0x1f,0xff,0xff,0xff,0xc0,0x7e,0xf,0xff,0xff,0xff,0x80,0xfe,0x7,0xff,0xff,0xff,0xc3,0xfc,0x3,0xff,0xff,0xff,0xff,0xf8,0x1,0xff,0xff,0xff,0xff,0xf0,0x0,0xff,0xff,0xff,0xff,0xe0,0x0,0x7f,0xff,0xf3,0xff,0xc0,0x0,0x3f,0xff,0xe0,0x7e,0x0,
0x0,0x1f,0xff,0xc0,0x0,0x0,0x0,0xf,0xff,0x80,0x0,0x0,0x0,0x7,0xff,0x0,0x0,0x0,0x0,0x3,0xfe,0x0,0x0,0x0,0x0,0x3,0xfe,0x0,0x0,0x0,0x0,0x1,0xfc,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,0x0,
0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,0x0,
0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x0,0xf8,0x0,0x0,0x0,0x0,0x1,0xfc,0x0,0x0,0x0,0x1,0xff,0xff,0xfc,0x0,0x0,0x3,0xff,0xff,0xfe,0x0,0x0,0x3,0xff,0xff,0xfe,0x0,0x0,0x3,0xff,0xff,0xfe,0x0,0x0,0x1,0xff,0xff,0xfc,0x0,0x0
  
};


void draw(void) {
  // graphic commands to redraw the complete screen should be placed here  
  u8g.drawBitmapP( 20, 20, 1, 20, cocktail);
}

void setup(void) {
}

void loop(void) {
  // picture loop
  u8g.firstPage();  
  do {
    draw();
  } while( u8g.nextPage() );
  
  // rebuild the picture after some delay
  delay(1000);
}

I haven't understood well how the draw syntax works, even if I've read the doc...

u8g.drawBitmapP( 20, 20, 1, 20, cocktail);

I'm additionally not sure if the hex is valid.

Could someone help me?

Thank's!

Simon

cocktail.png

Hi

Here is the procedure, which was successful at least for me:

  1. Load your picture into gimp
  2. Convert it into a indexed bitmap, 2 levels, black & white, maybe use dithering
  3. Export as XBM (.xbm extension)

Result will be something like this. Copy the content of the .xbm file into your .ino file:

#define u8g_logo_width 38
#define u8g_logo_height 24
static unsigned char u8g_logo_bits[] = {
   0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xe0, 0xe0,
   0xff, 0xff, 0x3f, 0xe3, 0xe1, 0xff, 0xff, 0x3f, 0xf3, 0xf1, 0xff, 0xff,
   0x3f, 0xf3, 0xf1, 0xfe, 0xbf, 0x37, 0xf3, 0x11, 0x1c, 0x1f, 0x30, 0xf3,
   0x01, 0x08, 0x8c, 0x20, 0xf3, 0x01, 0x00, 0xc0, 0x39, 0xf3, 0x81, 0xc7,
   0xc1, 0x39, 0xf3, 0xc1, 0xc7, 0xc9, 0x38, 0xf3, 0xc1, 0xc3, 0x19, 0x3c,
   0xe3, 0x89, 0x01, 0x98, 0x3f, 0xc7, 0x18, 0x00, 0x08, 0x3e, 0x0f, 0x3c,
   0x70, 0x1c, 0x30, 0x3f, 0xff, 0xfc, 0x87, 0x31, 0xff, 0xff, 0xbf, 0xc7,
   0x23, 0x01, 0x00, 0x00, 0xc6, 0x23, 0x03, 0x00, 0x00, 0x0e, 0x30, 0xff,
   0xff, 0x3f, 0x1f, 0x3c, 0xff, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0xff, 0x3f,
   0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x3f };
  1. Add the PROGMEM statement to move the picture into flash rom:
#define u8g_logo_width 38
#define u8g_logo_height 24
static unsigned char u8g_logo_bits[] U8G_PROGMEM = {
   0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xe0, 0xe0,
   0xff, 0xff, 0x3f, 0xe3, 0xe1, 0xff, 0xff, 0x3f, 0xf3, 0xf1, 0xff, 0xff,
   0x3f, 0xf3, 0xf1, 0xfe, 0xbf, 0x37, 0xf3, 0x11, 0x1c, 0x1f, 0x30, 0xf3,
   0x01, 0x08, 0x8c, 0x20, 0xf3, 0x01, 0x00, 0xc0, 0x39, 0xf3, 0x81, 0xc7,
   0xc1, 0x39, 0xf3, 0xc1, 0xc7, 0xc9, 0x38, 0xf3, 0xc1, 0xc3, 0x19, 0x3c,
   0xe3, 0x89, 0x01, 0x98, 0x3f, 0xc7, 0x18, 0x00, 0x08, 0x3e, 0x0f, 0x3c,
   0x70, 0x1c, 0x30, 0x3f, 0xff, 0xfc, 0x87, 0x31, 0xff, 0xff, 0xbf, 0xc7,
   0x23, 0x01, 0x00, 0x00, 0xc6, 0x23, 0x03, 0x00, 0x00, 0x0e, 0x30, 0xff,
   0xff, 0x3f, 0x1f, 0x3c, 0xff, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0xff, 0x3f,
   0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0xff, 0x3f };
  1. Then use the following code:
 u8g.drawXBMP( 0, 0, u8g_logo_width, u8g_logo_height, u8g_logo_bits);

Oliver

Thank you! This worked for me too!

Thank you a lot, it works well on the example.
I've only a little problem. If I move the example in my sketch, I obtain this error:

error: cocktail_bits causes a section type conflict

I need to remove the 'U8G_PROGMEM' statement from 'cocktail_bits' definition and draw with 'u8g.drawXBM' instead of 'u8g.drawXBMP'.

I'm using other includes, maybe conflict?

#include <SPI.h>
#include <avr/pgmspace.h>
#include "printf.h"
#include <RF24Network.h>
#include <RF24.h>
#include "nodeconfig.h"
#include <OneWire.h>
#include <DallasTemperature.h>

Why?

TY!

Simon

You could try PROGMEM instead of U8G_PROGMEM.

Methods to move data from RAM to FLASHROM do not work that well with the g++ compiler (the one used by Arduino IDE).
Additionally behavior has changed during versions of g++.
U8G_PROGMEM is a little bit different to PROGMEM and was optimized for the gcc compiler. Maybe this has caused the problem.

Oliver

olikraus:
You could try PROGMEM instead of U8G_PROGMEM.

Methods to move data from RAM to FLASHROM do not work that well with the g++ compiler (the one used by Arduino IDE).
Additionally behavior has changed during versions of g++.
U8G_PROGMEM is a little bit different to PROGMEM and was optimized for the gcc compiler. Maybe this has caused the problem.

Oliver

Same error:

static unsigned char cocktail_bits[] PROGMEM = {
error: cocktail_bits causes a section type conflict

:frowning:

Try this:

  • Replace "static" with "const" or
  • Remove "static" or
  • Add "const"

Oliver

olikraus:
Try this:

  • Replace "static" with "const" or
  • Remove "static" or
  • Add "const"

Oliver

This works!
Could you explain me why or point me where to read about it?

const unsigned char cocktail_bits[] U8G_PROGMEM

Thank you a lot!

The only strange behaviour is that in PROGMEM doesn't always draw/react well... :frowning:

Have a nice one!

Simon

Could you explain me why or point me where to read about it?

Good question. Some years back, "const" was not required. For example this page avr-libc: Data in Program Space does not mention, that "const" is required along with PROGMEM. Indeed examples at avr-libc: Data in Program Space are wrong (meanwhile?).

After some search, i found this page: Named Address Spaces - Using the GNU Compiler Collection (GCC)
This is part of the release doc for gcc 4.7.1 which explains, that the "const" keyword is required for "read only data" like PROGMEM area.

Oliver

Thank you again for your support.
I'll test my sketch with and without PROGMEM to look which one seems more stable.

Bye!

Simon

Just found this and it's helped me !!!! THX

Only now need to try and find a good way in GIMP to convert my Clipart into 8bit graphics (not going to well at the mo as lines are being missed) or find a site that has 8bit black and white clip art :slight_smile: