SSD1306Ascii
SSD1306Ascii copied to clipboard
how to display bitmap
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!
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.
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
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.
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
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.
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.
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.
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.
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.
@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!
@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.
@DirtyEngineer
Thanks 👍 I'll give it a go
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.
// '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++;
}
}
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 👍
👋 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;
}
}
}
}
// ...
};