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

how to display bitmap #57

Open
hzc1111 opened this issue Mar 20, 2019 · 11 comments
Open

how to display bitmap #57

hzc1111 opened this issue Mar 20, 2019 · 11 comments

Comments

@hzc1111
Copy link

hzc1111 commented Mar 20, 2019

I tried to use the function **ssd1306WriteRam (uint8_t c)** to display some points on the screen, but I couldn't display them by coordinates, and I wanted to display some graphics or characters obtained by the modulo software but I couldn't implement them (I am a programming newcomer). 
I really like this library because it's really small, it's very helpful for my development, but I don't want to give it up and use other libraries that are more powerful but use more storage, so I hope you can help a little. thank you very much!
@greiman
Copy link
Owner

greiman commented Mar 20, 2019

You can't really implement bit map graphics without lots of RAM buffer.

That's the trade off, SSD1306Ascii gives up bitmap graphics to save 1 KB of RAM.

@DirtyEngineer
Copy link

DirtyEngineer commented Mar 20, 2019

You can use this library to display graphics it just takes a little preprocessing to get it to work.

Example 1: Display a 8x8 custom character

8x8 pixel image
Pointer

You need to convert the image to a hex array by saving the image as a xbm file or using Image2LCD software. What this does is convert the pixels into a byte array in the format shown below. Think of each bit as a pixel that is either 0 for off or 1 for on.

Imagebytes

The display accepts these values but in hex format. Here is our image converted to this format.
0x7E,0xE7,0xE7,0xA5,0x81,0xC3,0xE7,0x7E

To access the image in your sketch you should store it in flash memory like this
const uint8_t Pointer[8] PROGMEM = {0x7E,0xE7,0xE7,0xA5,0x81,0xC3,0xE7,0x7E};

To display the image you use oled.setCursor and then use oled.ssd1306WriteRam to transfer each value in the array

oled.setCursor(0,0);
for (byte i = 0; i < 8; i++) oled.ssd1306WriteRam(pgm_read_byte(&Pointer[i]));

Example 2: Display a 32x32 image

Dirty Engineer - 32x32

You can use larger images but you need to slightly modify or call them differently as the display writes in 8 pixel high rows. A 32 pixel high image has 4 rows. Using the technique mentioned above we convert the image and for easy of understanding I've added an empty line between each row of data.

const byte Logo[128] PROGMEM = {
    0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xE0, 
    0x60,0x30,0x30,0x18,0x18,0x1C,0x1C,0x0C,
    0x0C,0x0C,0x0C,0x1C,0x1C,0x18,0x18,0x38, 
    0x30,0x70,0xE0,0xC0,0x80,0x00,0x00,0x00, // Row 0
    
    0x00,0xE0,0xF8,0x3E,0x0F,0x03,0x01,0x00,
    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
    0x80,0x80,0xC0,0xC0,0x40,0x60,0x20,0x20,
    0x20,0x20,0x20,0xE1,0x23,0x27,0xFE,0xF8, // Row 1
    
    0x00,0x1F,0x3F,0xF2,0xC2,0x8E,0x3F,0xE3,
    0x81,0x81,0x80,0x80,0x80,0xB8,0xD8,0x61,
    0x1F,0x01,0x03,0x0E,0x18,0x36,0x2E,0x20,
    0xA0,0xB0,0xD8,0xEF,0x70,0x38,0x1F,0x07, // Row 2
    
    0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x06,
    0x0E,0x0D,0x0D,0x1D,0x3D,0x78,0x70,0x30,
    0x3E,0x1E,0x18,0x18,0x1F,0x0F,0x0C,0x0C,
    0x07,0x07,0x07,0x00,0x00,0x00,0x00,0x00}; // Row 3

Now to write the image to the display we need add some code to write the first row, set the cursor for the second row, write the second row...etc..etc.

 byte r = 1; // Start row - Modify as needed
 byte c = 10; // Start col - Modify as needed
 byte a = 0; // Position in array - Don't change - an array larger than 256 will need to use "int = a"
  for (byte b = 0; b < 4; b++) {
    oled.setCursor (c,(r+b)); 
    for (byte i = 0; i < 32; i++) {
      oled.ssd1306WriteRam(pgm_read_byte(&Logo[a]));
      a++;
     }  
   }

Here is a quick and potato quality video of using both of these examples with this library.

@greiman
Copy link
Owner

greiman commented Mar 20, 2019

By graphics I mean a typical 2D API to draw points, lines, rectangles, circles, fill...

Yes, you can write bitmaps but I don't plan on graphic extensions like Adafruit GFX.

@DirtyEngineer
Copy link

Agreed, graphics such as that are outside of the scope of this wonderful little library. If you need something like that you might check out this library as it includes these features while trying to maintain minimal size.

@krukhlis
Copy link

Guys, the name of this library has Ascii suffix -- it should be sufficient to understand its main goal. 2D API is completely different functionality, requiring too much memory and CPU power. There are lots of libraries that provide it -- Adafruit's GFX, u8g, u8g 2, ssd1306, etc. SSD1306Ascii has different purpose and suits best and better than any other lib exactly these Ascii purpose only.

@hzc1111
Copy link
Author

hzc1111 commented Mar 21, 2019

Indeed, this library is simple and practical in displaying the Ascii, the grammar is simple and clear, which is why I want to improve on it. In any case, this is a learning process, thank you for your reply.

@IAmOrion
Copy link

IAmOrion commented Mar 22, 2019

@DirtyEngineer Would you share you example code?
Also, I feel like I'm being super stupid, but, I have an image that's 128x64 (Technically, I could make it 64x64 but would want it centered)... how do I adapt your code?

I realised your code requires the image to be done VERTICALLY... but other than that I just can't figure it out and I know it's gonna be me being dumb (I'll blame it on a senior moment).

Best I've got so far is (I realise I've "broken" it already so to speak but no matter what I tried, it wouldn't show right):

[I Removed the code I had posted - I was tired, I realised the error!]

Side Note: I really want that as a "splashscreen" kind of thing & would love to have it slide into view like your video (from top or bottom in my case though)

I'm an idiot - I just twigged you're using byte in you counter which maxes out at 255, which is why my logo wasn't working (1024 length)...

   byte r = 0; // Start row - Modify as needed
   byte c = 0; // Start col - Modify as needed
   int a = 0; // Position in array - Don't change
    for (byte b = 0; b < 8; b++) {
      display.setCursor (c,(r+b)); 
      for (int i = 0; i < 128; i++) {
        display.ssd1306WriteRam(pgm_read_byte(&BMWLogo[a]));
        a++;
       }  
     }

It works now!

@DirtyEngineer
Copy link

DirtyEngineer commented Mar 22, 2019

@IAmOrion Glad you picked up on the byte counter problem. Scrolling the image sideways is pretty simple with this library. Just add another for loop for the "c" variable. (Oh and be sure to use oled. instead of display.)

 for( byte c = 127; c > 32; c-- ){
   byte r = 0; // Start row - Modify as needed
   int a = 0; // Position in array - Don't change
   for (byte b = 0; b < 8; b++) {
     oled.setCursor (c,(r+b)); 
     for (byte i = 0; i < 64; i++) {
       oled.ssd1306WriteRam(pgm_read_byte(&BMWLogo[a]));
       a++;
      }  
    }
  }

Notice the c variable is decreasing? The image will slide in from the right to left. The library ignores any data written past column 127 and will truncate the image so it slides in smoothly. If you were to go from left to right you would have to display the entire image as you can't have a negative column start point. You don't notice it much with smaller images but yours is half the screen so it doesn't look right. You could probably get fancy with reading the array in progressively larger chunks until the full image is shown and then increment the column position but that's for another day.

You'll need to truncate our image for the above code to work. I quick and dirty commented out the unneeded portions.

const byte BMWLogo[1024] PROGMEM = {
//  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, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 
  0x40, 0x60, 0x20, 0x30, 0x10, 0x10, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0xf4, 0x74, 0xc4, 0x04, 
  0x04, 0xe4, 0x74, 0xf4, 0x04, 0x04, 0x04, 0x08, 0x08, 0x08, 0x10, 0x10, 0x30, 0x20, 0x60, 0x40, 
  0x80, 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, 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, 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, 0xc0, 0x60, 0x10, 0x48, 0xe4, 0x92, 0x89, 0xc9, 0x78, 
  0x20, 0xe0, 0xc0, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x27, 0x20, 0x21, 0x27, 
  0xa7, 0xe1, 0xe0, 0xa7, 0xa0, 0xe0, 0xc0, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xe0, 
  0x98, 0x4d, 0x41, 0xe2, 0x64, 0x08, 0x10, 0x60, 0xc0, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0xc0, 0x38, 0x0e, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x06, 0xc4, 
  0x32, 0x19, 0x0c, 0x06, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfd, 0xfb, 0xfe, 0xec, 0xd9, 0xb1, 
  0xc0, 0x0c, 0x0f, 0x05, 0x06, 0x02, 0x03, 0x01, 0x00, 0x03, 0x0e, 0x38, 0xc0, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x03, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xfc, 0x67, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xfe, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x7f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe6, 0x7f, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7f, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x03, 0x1c, 0x70, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 
  0x0d, 0x1b, 0x37, 0x6f, 0xdf, 0xbf, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0x60, 0x30, 0x18, 0x0c, 
  0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x70, 0x1c, 0x03, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x00, 
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x07, 0x05, 0x05, 0x07, 0x07, 0x05, 
  0x04, 0x04, 0x04, 0x04, 0x04, 0x06, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  0x00, 0x80, 0x80, 0x40, 0x20, 0x10, 0x08, 0x06, 0x03, 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, 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, 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, 0x01, 0x01, 
  0x02, 0x06, 0x04, 0x0c, 0x08, 0x08, 0x10, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x08, 0x08, 0x0c, 0x04, 0x06, 0x02, 
  0x01, 0x01, 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, 0x00, 
//  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

If you really want it to slide the image from top to bottom smoothly, I suggest using another library with a buffer as this one isn't setup to do something like that. You need to be able to set the row from 0-63 instead of 0-7 as you will only have 8 frames to scroll the image.

@IAmOrion
Copy link

@DirtyEngineer

Thanks 👍 I'll give it a go

@LucaUrbinati44
Copy link

I add a contribution to @DirtyEngineer's answers. I used his code to plot a full screen 128x32 image on my OLED. Here is my code, maybe someone can be interested in.

Schermata 2020-02-27 alle 23 28 05

// 'logo', 128x32px
const unsigned char logo [512] PROGMEM = { // Draw mode: vertical - 1 bit per pixel
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x3f, 0x9f, 0x8f, 0x0f, 
  0x07, 0x07, 0x37, 0x37, 0x3b, 0x3b, 0x33, 0x63, 0x63, 0xc3, 0xc3, 0x83, 0x87, 0x07, 0x07, 0x07, 
  0x0f, 0x1f, 0x3f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x0f, 0x03, 0xfe, 0xff, 0x7f, 0x3f, 0x3f, 0x3f, 
  0x3c, 0x78, 0xf8, 0xf0, 0xf0, 0xf0, 0xf8, 0xf8, 0x7c, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x1e, 0x00, 
  0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x3c, 0x70, 0x00, 0x00, 
  0x00, 0x00, 0xe1, 0xff, 0xff, 0xff, 0xf7, 0xc0, 0xc0, 0xc0, 0x60, 0x60, 0x38, 0xbc, 0xde, 0xe0, 
  0xf0, 0xf8, 0xfc, 0xff, 0xf7, 0x01, 0xf6, 0xf7, 0xff, 0x6f, 0x77, 0xb7, 0xb7, 0x0f, 0xff, 0xff, 
  0x00, 0xf7, 0xf7, 0xf7, 0x07, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x6f, 0x77, 0xb7, 0xb7, 0x0f, 
  0xff, 0xff, 0x00, 0xf7, 0xf7, 0xf7, 0x07, 0xff, 0xff, 0x07, 0x07, 0xf7, 0xf7, 0x1f, 0x07, 0xf7, 
  0xf7, 0x07, 0x0f, 0xff, 0x07, 0x07, 0xf7, 0xf7, 0x07, 0x07, 0xf7, 0x07, 0x0f, 0xff, 0xff, 0x67, 
  0x37, 0xb7, 0xa7, 0x0f, 0xff, 0xff, 0x07, 0x67, 0x77, 0x77, 0x03, 0xf3, 0xff, 0x07, 0x07, 0xf7, 
  0xf7, 0x07, 0x0f, 0xff, 0x6f, 0x27, 0x37, 0xb7, 0x07, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xf8, 0xf0, 0xf0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 
  0xe0, 0xe0, 0xe1, 0xf3, 0xf7, 0xfb, 0xfb, 0xf9, 0xfd, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 
  0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xff, 0xff, 0xff, 0xfc, 0xfb, 0xfb, 0xfd, 0xf8, 0xff, 0xff, 
  0xf8, 0xfd, 0xfb, 0xfb, 0xfc, 0xff, 0xff, 0xfc, 0xfd, 0xfb, 0xff, 0xfc, 0xfb, 0xfb, 0xfd, 0xf8, 
  0xff, 0xff, 0xf8, 0xfd, 0xfb, 0xfb, 0xfc, 0xff, 0xff, 0xfc, 0xf8, 0xff, 0xff, 0xfe, 0xfc, 0xf9, 
  0xf9, 0xfc, 0xfe, 0xff, 0xfc, 0xf8, 0xff, 0xff, 0xf8, 0xfc, 0xff, 0xfc, 0xf8, 0xff, 0xff, 0xfc, 
  0xf9, 0xf9, 0xfc, 0xf8, 0xff, 0xff, 0xe0, 0xc8, 0xd8, 0xdd, 0xc1, 0xf3, 0xff, 0xfc, 0xf8, 0xff, 
  0xff, 0xf8, 0xf8, 0xff, 0xfc, 0xfc, 0xf9, 0xf9, 0xf8, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};

// for a 128x32 image
  byte r = 0; // Start row
  byte c = 0 ; // Start col
  int a = 0; // Position in array - Don't change - an array larger than 256 will need to use "int = a"
  for (byte b = 0; b < 4; b++) { // I'm expecting to occupy all the 4 rows of the display
    oled.setCursor (c,(r+b)); 
    for (byte i = 0; i < 128; i++) { // since I need to occupy all the 4 rows of the display, I divided the number of elements of the logo array (512) by 4. This is why I got 128.
      oled.ssd1306WriteRam(pgm_read_byte(&logo_bmp[a]));
      a++;
    }  
  }

photo_2020-02-27 23 32 38

I conclude with this fantastic website that helped me to obtain a bitmap image from a normal one: https://javl.github.io/image2cpp/.

Thank you @DirtyEngineer 👍

@H4ckd4ddy
Copy link

H4ckd4ddy commented Jun 28, 2021

👋
If you want to use the image format provided in the Adafruit SSD1306 lib examples, like this one :

static const unsigned char PROGMEM logo16_glcd_bmp[] =
{ B00000000, B11000000,
  B00000001, B11000000,
  B00000001, B11000000,
  B00000011, B11100000,
  B11110011, B11100000,
  B11111110, B11111000,
  B01111110, B11111111,
  B00110011, B10011111,
  B00011111, B11111100,
  B00001101, B01110000,
  B00011011, B10100000,
  B00111111, B11100000,
  B00111111, B11110000,
  B01111100, B11110000,
  B01110000, B01110000,
  B00000000, B00110000 };

I made this simple function :

void drawBitmap(int16_t offset_x, int16_t offset_y, const uint8_t *bitmap, int16_t w, int16_t h, uint8_t color) {
  byte chunk = 0;
  for(byte column = 0; column < w; column++){
    for(byte line = 0; line < h; line++){
      int pos = ((line*w)+column);
      int byte_pos = pos/8;
      int bit_pos = 7-(pos%8);
      if(bitRead(pgm_read_byte(bitmap + byte_pos), bit_pos)){
        bitSet(chunk, (line%8));
      }
      if((line % 8) == 7){
        setCursor(offset_x + column, offset_y + line);
        ssd1306WriteRam(chunk);
        chunk = 0;
      }
    }
  }
}

And you can even extend lib class to handle some other SSD1306 lib method, to avoid rewriting working code with the Adafruit lib.

class Adafruit_SSD1306 : public SSD1306AsciiAvrI2c {
  public:
    virtual void setTextSize(uint8_t text_size){
      switch(text_size){
        case 1: set1X();break;
        case 2: set2X();break;
      }
    }
    virtual void setCursor(uint8_t x, uint8_t y){
      setCol(x);
      setRow(y/8);
    }
    virtual void display(){}
    virtual void clearDisplay(){
      clear();
    }
    virtual void drawBitmap(int16_t offset_x, int16_t offset_y, const uint8_t *bitmap, int16_t w, int16_t h, uint8_t color) {
      byte chunk = 0;
      for(byte column = 0; column < w; column++){
        for(byte line = 0; line < h; line++){
          int pos = ((line*w)+column);
          int byte_pos = pos/8;
          int bit_pos = 7-(pos%8);
          if(bitRead(pgm_read_byte(bitmap + byte_pos), bit_pos)){
            bitSet(chunk, (line%8));
          }
          if((line % 8) == 7){
            setCursor(offset_x + column, offset_y + line);
            ssd1306WriteRam(chunk);
            chunk = 0;
          }
        }
      }
    }
    // ...
};

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

7 participants