Bitmap to HEX for OLED Display ! I don´t get it to work !

Hello everybody,
I could need some help to convert a bitmap picture to a working HEX code for the u8g2 library. I know how to do it, but it´s just not working. :slight_smile:

I used a LCD Immage Converter to generate the code. If I up load the "immage code" to my Arduino, it´s just not displaying right. All I get to see is a square of random pixles. I just can´t find anything in the internet that works for me.

If I copy a HEX code of a bitmap from another example scatch, this is working, but if I try to make my own by using a converter, they don´t and I don´t know why !

I just did the same like some youtuber, nothing ! Didn´t work.

Is there anybody who can help me ? What do I do wrong ?

Here is my code.
The "batt" bmp doesn´t work, the "cross_bits" bmp works.

the "batt" is the one that I created by using a converter, I tryed different converters but same result !??


 
#include <Arduino.h>
#include <U8g2lib.h>

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif


U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

#define cross_width 50
#define cross_height 20
const unsigned char batt[] {
 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 
    0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 
    0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 
    0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 
    0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 
    0x00, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x3f, 
    0x00, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x3f, 
    0x00, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x3f, 
    0x00, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x3f, 
    0x00, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x3f, 
    0x00, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x3f, 
    0x00, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x3f, 
    0x00, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x3f, 
    0x00, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x3f, 
    0x00, 0xff, 0xff, 0xff, 0xff, 0xf8, 0x3f, 
    0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 
    0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 
    0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 
    0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 
    0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
};



#define cross_width 24
#define cross_height 24
static const unsigned char cross_bits[] U8X8_PROGMEM  = {
  0x00, 0x18, 0x00, 0x00, 0x24, 0x00, 0x00, 0x24, 0x00, 0x00, 0x42, 0x00, 
  0x00, 0x42, 0x00, 0x00, 0x42, 0x00, 0x00, 0x81, 0x00, 0x00, 0x81, 0x00, 
  0xC0, 0x00, 0x03, 0x38, 0x3C, 0x1C, 0x06, 0x42, 0x60, 0x01, 0x42, 0x80, 
  0x01, 0x42, 0x80, 0x06, 0x42, 0x60, 0x38, 0x3C, 0x1C, 0xC0, 0x00, 0x03, 
  0x00, 0x81, 0x00, 0x00, 0x81, 0x00, 0x00, 0x42, 0x00, 0x00, 0x42, 0x00, 
  0x00, 0x42, 0x00, 0x00, 0x24, 0x00, 0x00, 0x24, 0x00, 0x00, 0x18, 0x00, };



void setup(void) {
  u8g2.begin();
}

void loop(void) {
  u8g2.clearBuffer();					// clear the internal memory
  u8g2.setFont(u8g2_font_ncenB08_tr);	// choose a suitable font
 // u8g2.drawStr(20,30,"Hello World!");	// write something to the internal memory
  u8g2.drawXBMP(30, 20, 50, 20, batt);  // Draw Bitmap  (lins/rechts, hoch/runter, width, hight, picture)
  u8g2.sendBuffer();					// transfer internal memory to the display
   
}


Tell us what happens here ?


void loop(void) {
  u8g2.clearBuffer();					// clear the internal memory
  u8g2.setFont(u8g2_font_ncenB08_tr);	// choose a suitable font
 // u8g2.drawStr(20,30,"Hello World!");	// write something to the internal memory
  u8g2.drawXBMP(30, 20, 50, 20, batt);  // Draw Bitmap  (lins/rechts, hoch/runter, width, hight, picture)
  u8g2.sendBuffer();					// transfer internal memory to the display
   
}

Image need to be stored in PROGMEM

const unsigned char batt[] PROGMEM {

Thanks, you are right ! I forgot !!! PROGMEM !!!

It looks better now. Still not right but I am getting there ! :slight_smile:
The problem I have now must be the settings of the Bitmap Converter.
It looks like it´s inverted. I have to play with the settings. But it looks better now ! Not just like random pixles.
Thanks !

The image format is XBM, not bitmap.

There are two functions in the U8g2 library for drawing XBM format images, drawXBM() and drawXBMP(). drawXBM() is for images stored in ram, drawXBMP() is for images stored in PROGMEM.

There is also a drawBitmap() function for actual bitmaps, the image must be stored in PROGMEM.

The difference between the XBM and bitmap image format is that the bit order within each byte is reversed. With XBM, the leftmost bit in the image is the least significant bit of the first byte.

Thanks for the answer !
Ok. I understand. Now, I know how to deal with it. I just have got the next problem.

I made my own bitmap symbol, just a battery.
I used Win. Paint to make that.
Saved it as Monocrom Bitmap and used a LDC_Bitmap_Converter to get the HEX code of it. so far so good !
If I upload it, it looks like my battery but, it is cut in 3 peaces and mirrored.
I was sitting on that LCD converter for hours and played around with the settings. Can´t find out whats going on.
If I use another Bitmap converter, I get just a destorted picture on the screen.
I took pictures of it, just take a look. :slight_smile:

LCD_immage_con

Hexcode

That´s the code :

//this is an example of the Oled Display 1.3"
 
#include <Arduino.h>
#include <U8g2lib.h>

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif


U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

#define cross_width 22
#define cross_height 8
static const unsigned char batt[] U8X8_PROGMEM = {
0x3f, 0xff, 0xfc, 
    0x20, 0x00, 0x04, 
    0xe0, 0x00, 0x04, 
    0xa0, 0x00, 0x04, 
    0xa0, 0x00, 0x04, 
    0xe0, 0x00, 0x04, 
    0x20, 0x00, 0x04, 
    0x3f, 0xff, 0xfc
 };




#define cross_width 24
#define cross_height 24
static const unsigned char cross_bits[] U8X8_PROGMEM  = {
  0x00, 0x18, 0x00, 0x00, 0x24, 0x00, 0x00, 0x24, 0x00, 0x00, 0x42, 0x00, 
  0x00, 0x42, 0x00, 0x00, 0x42, 0x00, 0x00, 0x81, 0x00, 0x00, 0x81, 0x00, 
  0xC0, 0x00, 0x03, 0x38, 0x3C, 0x1C, 0x06, 0x42, 0x60, 0x01, 0x42, 0x80, 
  0x01, 0x42, 0x80, 0x06, 0x42, 0x60, 0x38, 0x3C, 0x1C, 0xC0, 0x00, 0x03, 
  0x00, 0x81, 0x00, 0x00, 0x81, 0x00, 0x00, 0x42, 0x00, 0x00, 0x42, 0x00, 
  0x00, 0x42, 0x00, 0x00, 0x24, 0x00, 0x00, 0x24, 0x00, 0x00, 0x18, 0x00, };



void setup(void) {
  u8g2.begin();
}

void loop(void) {
  u8g2.clearBuffer();					// clear the internal memory
 // u8g2.setFont(u8g2_font_ncenB08_tr);	// choose a suitable font
 // u8g2.drawStr(20,30,"Hello World!");	// write something to the internal memory
  u8g2.drawXBMP(35, 20, 22, 8, batt);  // Draw Bitmap  (lins/rechts, hoch/runter, width, hight, picture)
  //u8g2.drawXBMP(35, 20, 24, 24, cross_bits);  // Draw Bitmap  (lins/rechts, hoch/runter, width, hight, picture)
  u8g2.sendBuffer();					// transfer internal memory to the display
   
}


This will properly display your battery:

static const unsigned char batt[] PROGMEM = {
  0xfc, 0xff, 0x3f,
  0x04, 0x00, 0x20,
  0x07, 0x00, 0x20,
  0x05, 0x00, 0x20,
  0x05, 0x00, 0x20,
  0x07, 0x00, 0x20,
  0x04, 0x00, 0x20,
  0xfc, 0xff, 0x3f
};

Notice the bit order within each byte is reversed. That is the difference between a bitmap image and an XBM image.

Nope !
Unfortunatelli it looks the same ! :frowning:

The problem must be somewhere else ! ?!?
I am going crazy ! :slight_smile:

Sorry ! It does work !
I just made a mistake copieying it into my scetch !
Cool !
Now, I can create my project because I know all I have to know. !
Thank you so much !

you can test your bitmaps here

I don´t realy get it !
Why is your Hexcode showing a battery and mine not propperly ?
I can do what ever I want, I can´t generate an immage on the screen that is not out of shape ! Your Hex code looks different then mine, why ? How did you do it ?
Cheers ! What kind of converter do you use ?

Actually I manually changed the hex code to reverse the bit order in each byte, but that is not practical with anything but the smallest image.
Not really sure where to find an online converter to generate c++ code in XBM format, in the past I've written code for an arduino that would take the bitmap, reverse the bits in each byte, and print that out to the Serial monitor so I could copy/paste it.

1 Like

he just read the bits from right to left instead of left to right

your first byte is 0x3F = 00111111
image
it's matching the pixels from your battery : 0 white dot, 1 black dot

but for the bitmap to be printed correctly, you need to read the bits the other way so 00111111 becomes 11111100 which is 0xfc

0xff has all the bits to 1, so it stays the same

0xfc is 11111100 becomes 00111111 which is 0x3f

so if you look at the start of your battery bitmap

0x3f, 0xff, 0xfc,
whilst @david_2018 has
0xfc, 0xff, 0x3f,

➜ all the bits have been reversed

do the same for all the bytes

This is so complicated !
I don´t realy understand the system of HEX code. I tried it but I just don´t understand it. Maby one day... Anyways, I don´t have to understand it. I just want to use it, right ?
But I think if my generated code is in the wrong way, it´s a problem of my converter. Basicly, it should work to generate a code and copy/paste it. I saw that many times in the internet but for some magical reason, this is not working for me. Even if I use the same software and hardware ! ???? Magic ???
The next funny thing is, if I try another converter, like some online converters, I get alwas another code for the same immage, depending on the converter. ??? The only converter that "kind of " works is the LCD Immage Converter but it´s converting in the wrong way. Well ! I guess that´s the problem, the converter !
:slight_smile:
Thanks so far.

Is it possible to use byte arrays like in the Adafruit 1306 library ?
That would make things a lot easyer for me.

cheers

Actually the Adafruit library would work with the code you got from the LCD Image Converter, Adafruit uses bitmap format instead of XBM.

OK ! Good to know.
I just have the problem that the there is no library from Adafruit that supports my Displays. like SSD1309 or SH1106.
I basicly use the Adafruit library SSD1306 a lot.

I just tryed it with the adafruit library on a SSD1306 Display. It works, but same issue ! The bitmap is disordered in the same way. No change.
Well then it´s the converter !

Did you use the image array that I posted, or the original one from your sketch?

If i upload yours to the adafruit lb. it works and looks good. But if I generate the code with LCD immage converter then it is disordered. It must be the Converter.
I have to find onother converter and try that !