Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document ssd1306_display_image #17

Open
ghost opened this issue Apr 25, 2022 · 13 comments
Open

Document ssd1306_display_image #17

ghost opened this issue Apr 25, 2022 · 13 comments

Comments

@ghost
Copy link

ghost commented Apr 25, 2022

I'm trying to figure out how to use ssd1306_display_image() to display a monochrome image stored in a byte buffer.
There is no documentation or samples on how to do this.

@nopnop2002
Copy link
Owner

nopnop2002 commented Apr 25, 2022

oid ssd1306_display_image(SSD1306_t * dev, int page, int seg, uint8_t * images, int width)

documentation about page and seg(=segment) is here.

https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf

@ghost
Copy link
Author

ghost commented Apr 25, 2022

Could you write or provide a helper function to draw bitmaps?
ex. https://www.mischianti.org/2021/07/14/ssd1306-oled-display-draw-images-splash-and-animations-2/

I'm reading the datasheet now, but I just need an abstraction API to draw a simple uint8_t byte buffer containing monchrome image data.

@nopnop2002
Copy link
Owner

nopnop2002 commented Apr 25, 2022

Bitmap drawing can be done with this function.

oid ssd1306_display_image(SSD1306_t * dev, int page, int seg, uint8_t * images, int width)

This is API to draw a simple uint8_t byte buffer containing monchrome image data.
You need to understand the pages and segments of ssd1306
One page consists of 128 segments.
One segment is 8 bits data.
The whole consists of 8 pages.

uint8_t page[8][128];
//make bitmap to page buffer.
for (int page=0;page<8;page++) {
ssd1306_display_image(&dev, page, 0, page[page], 128);
}

@ghost
Copy link
Author

ghost commented Apr 25, 2022

Like I posted in the other issue, having an abstraction that takes a XBM buffer would be ideal, because that is what everyone uses and the industry standard. I understand that at low-level you have to write the segments across each page... I read the datasheet. But having a function that abstracts the whole process (including size calculations) is nice to have and more people will use your library, simply because the rest are Arduino centric.

ESP32 with ESP-IDF for example cannot use U8G2 since it has a broken HAL for ESP32. Your I2C code worked out of the box for me.

@ghost
Copy link
Author

ghost commented Apr 25, 2022

A sample XBM:

const unsigned char logoMischianti [1024] PROGMEM = {
    // 'logoBN128x64, 128x64px
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x7f, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe7, 0xc0, 0x7f, 0xe7, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xe0, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x01, 0xf8, 0x0f, 0xff, 0xff, 0xf0, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x03, 0xff, 0xff, 0xc0, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0xff, 0xff, 0x00, 0x41, 0xe0, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0xe0, 0xf0, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0xe0, 0x70, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0xe0, 0x70, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x07, 0xe0, 0x00, 0xe0, 0x38, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x7f, 0xf0, 0x03, 0xe0, 0x00, 0xe0, 0x38, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x7f, 0xf0, 0x03, 0xc0, 0x1f, 0xff, 0x38, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x7f, 0xf0, 0x03, 0xe0, 0x1f, 0xff, 0x38, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x07, 0xe0, 0x00, 0x60, 0x38, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0xe0, 0x70, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0xe0, 0x70, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x7c, 0x3e, 0x00, 0xe0, 0xf0, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x00, 0xf8, 0x1f, 0x00, 0x61, 0xe0, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x03, 0xc0, 0x03, 0xe0, 0x07, 0xc0, 0x03, 0xc0, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x01, 0xf8, 0x0f, 0xc0, 0x03, 0xf0, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xff, 0xff, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0x07, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf0, 0x0f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x08, 0x10, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x46, 0x63, 0x31, 0x90, 0xff, 0x13, 0xc3, 0x8b, 0x91, 0xe5, 0xdc, 0x80, 0xf3, 0xbf, 0x00,
    0x00, 0x66, 0x73, 0x39, 0x90, 0xcd, 0x92, 0x24, 0x4c, 0x92, 0x26, 0x48, 0x81, 0x13, 0x27, 0x00,
    0x00, 0x2e, 0x57, 0x2b, 0x90, 0x88, 0x93, 0x04, 0x08, 0xd0, 0x24, 0x68, 0x81, 0x1a, 0x23, 0x00,
    0x00, 0x2a, 0xd5, 0x6a, 0xb0, 0x88, 0x91, 0xcc, 0x08, 0xd3, 0xe4, 0x68, 0x83, 0x1a, 0x63, 0x00,
    0x00, 0x2b, 0x95, 0xca, 0xe0, 0x88, 0x90, 0x64, 0x08, 0xd2, 0x24, 0x68, 0x81, 0x1a, 0x63, 0x00,
    0x00, 0x39, 0x9c, 0xce, 0x60, 0x88, 0x96, 0x24, 0x48, 0xd6, 0x64, 0x68, 0x81, 0x12, 0x27, 0x00,
    0x00, 0x11, 0x88, 0xc4, 0x6c, 0x88, 0x93, 0xc3, 0x88, 0xd3, 0xb4, 0x6e, 0x98, 0xf2, 0x3f, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00
};

@nopnop2002
Copy link
Owner

nopnop2002 commented Apr 25, 2022

a XBM buffer would be ideal, because that is what everyone uses and the industry standard.

Really?

I still don't understand the advantages of XBM buffer.

What are the benefits of using XBM buffer?

Is there an official specification for the XBM buffer?

If the XBM buffer format is officially present and this is very informative, I will make it.

ssd1306_display_xbm(&dev, logoMischianti);

@ghost
Copy link
Author

ghost commented Apr 25, 2022

Not sure if you are being serious but I'm certainly not going to pick an argument with a stranger over the Internet...

So, I will answer your questions and bask in some good karma:

  • XBM allows indexed 2-bit color images (read: black and white).
  • https://en.wikipedia.org/wiki/X_BitMap
  • Every other library supports it in some form or another. Pretty much every GFX and monochrome display for ESP32 supports it. I started using yours because I write my projects in plan C and I do not use the Arduino framework or its integrations in ESP-IDF.
  • Saves you the hassle of programmatically drawing things. Yeah, I get it, your screen as you read me right now is also a bitmap of X,Y coordinates and color bitmaps defining each pixel... And your operating system isn't drawing them directly, there are a few abstraction lawyers, HAL, etc, in between, correct?

I might be misinterpreting your reactions, but I think I will just let it be. Note that I did not even comment about box, circle or polygon drawing, which other libraries also do. I merely asked for XBM because it is literally the single most common use case scenario: have some text screens, logo as screensaver, perhaps a scrolling menu...

@nopnop2002
Copy link
Owner

I wanted to know this.

https://en.wikipedia.org/wiki/X_BitMap

@ghost
Copy link
Author

ghost commented Apr 25, 2022

I will cleanup the small helper function I wrote, but it assumes vertically drawn XBMP is already provided. I appreciate the work you put into this library already.

@nopnop2002
Copy link
Owner

nopnop2002 commented Apr 25, 2022

vertically drawn XBMP is already provided

Vertically drawn XBMP is difficult for humans to understand.

I am considering support for horizontally drawn XBMP.


The horizontal XBMP to vertical XBMP conversion function is complete.

I'm considering whether to draw on pages units fom 0 to 7 or introduce a coordinate system from 0 to 63

@ghost
Copy link
Author

ghost commented Apr 25, 2022

Indeed, it is cumbersome also because you need to convert the original image to the XBMP buffer knowing that it needs to be vertically drawn, so there is some transformation required, else the image will be drawn garbled (squeezed into a rectangle).

My helper function more or less follows this:

    uint8_t img[8][128];
    memcpy(&img, &xbmpbuf, sizeof(xbmpbuf));
    for (uint32_t page = 0; page < 8; page++)
        ssd1306_display_image(&ssd1306_dev, page, 1, img[page], 128);

This assumes 128x64 sized buffers, that can be obviously evenly divided into the 0..7 pages and 0..127 segments.
Your proposed function sounds far more convenient. Regarding coordinates, I'm partial to avoiding over engineering something, but you could use the lower-level coordinate API(s) to implement other drawing functions likely (graphing: lines, dots, or geometrical: boxes/rectangles, ellipsis, etc).

@nopnop2002
Copy link
Owner

I have added the functionality of XBM bitmap.

Thank you for telling me various things.

https://github.com/nopnop2002/esp-idf-ssd1306/tree/master/ImageDemo

@ghost
Copy link
Author

ghost commented Apr 26, 2022

No need to thank me, thank you for your time and effort. I will review the changes more closely but what I've seen looks good. Much cleaner than what I did.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant