STM32 - How does OLED_SetPixel work ?

Thread Starter

Xenon02

Joined Feb 24, 2021
504
Hello !

I've been trying to use OLED in STM32 and found some library for it. I tried to also understand what happens in each in case to change something inside of the library, and I've stumbled into a understanding problem.


C:
void OLED_SetPixel(uint8_t x, uint8_t y, bool color)
{
    if(x < 0 || x > SCREEN_WIDTH || y < 0 || y > SCREEN_HEIGHT)
        return;

    if(color == OLED_COLOR_BLACK)
        buffer[x + SCREEN_WIDTH * (y / 8)] &= ~(1 << (y % 8));    // Clear bit responsible for pixel
    else if(color == OLED_COLOR_WHITE)
        buffer[x + SCREEN_WIDTH * (y / 8)] |= (1 << (y % 8));    // Set bit responsible for pixel
}

void OLED_DrawBitmap(uint8_t x, uint8_t y, bool invert_color, uint8_t width, uint8_t height, const uint8_t* bitmap)
{
    uint8_t inverting_mask = invert_color ? 0xFF : 0x00;

    for(uint8_t i = 0; i < height/8; i++)
    {
        for(uint8_t j = 0; j < width; j++)
        {
            for(uint8_t k = 0; k < 8; k++)
            {
                OLED_SetPixel(x + j, y + 8*i + k, (inverting_mask ^ bitmap[width*i + j]) & (1 << k));
            }
        }
    }
}
The OLED_DrawBitmap was quite understandable in which each byte contained 8 bit height picture info.
The screen is 128x64 so when each byte is 8 bit height then there was 1024, and the variable "k" was to read each bit in this byte. So in total the was like 8 scans from 0 to 127 of 8 bit hight picture each.

So now it's time to each bit/pixel put into OLED_SetPixel. In many OLED library there was the same setpixel function in which the buffer was an array of buffer[1024]. So I checked at the code and putted max values, x = 127 and y = 63, (SCREEN_WIDTH = 128) so buffer[127 + 128*(63/8)] = > buffer[1135] it exceeded the array.

So I didn't understand how it works and it was weird as well because I could have x = 0 and y = 0 which indicated that in coordinates 0,0 I want to add a pixel so the buffer was buffer[0] okey, but if I want now pixel x = 0 and y = 1 then the buffer was buffer[0+128(1/8)] => buffer[16], and it was weird because it wasn't a shift of 128 bits like in OLED_DrawBitmap : (inverting_mask ^ bitmap[width*i + j]) & (1 << k)); in which the shift was exactly 128 from first line to second line. But in OLED_SetPixel I don't know.

And last example here is that x = 16 and y = 0 give me the same buffer as if I choose x = 0 and y = 1.

Like I said I don't understand complitelly how it works. If somebody have an idea how it works I would be really glad to hear it.
 

MrChips

Joined Oct 2, 2009
34,809
The screen is 128 x 64 = 8192 pixels.
The buffer size is 1024 bytes = 8192 bits.
Seems like a perfect match to me.
 

Thread Starter

Xenon02

Joined Feb 24, 2021
504
The screen is 128 x 64 = 8192 pixels.
The buffer size is 1024 bytes = 8192 bits.
Seems like a perfect match to me.
Yes the buffer size is perfect because it's maximal size is buffer[1024].
If you read again I've mentioned that when I put x = 127 (max value) and y =63 (max value), it will exceed that size of a buffer which will be : buffer[1135].


Not only that but how it works puzzel me.
When I pick x = 0 and y = 0 I get buffer[0] but if I pick x = 0 and y =1 then it will be buffer[16] I don't get it how it works ...
What's more is that there are even repeating numbers for example x = 16 and y = 0 => buffer[16], x = 0 and y = 1 => buffer[16]. How the hell it works and how it reads which piksels I've choosen from this buffer, when they repeat and have weird placement like 16 for x = 0 and y = 1.

I don't know if you've read everything ;>
But If something is not clear, tell me which part.
 

Thread Starter

Xenon02

Joined Feb 24, 2021
504
Your math is wrong.
63 / 8 = 7
127 + 128 x 7 = 1023
Ahh yes you are totally right ;>
I did a simple mistake in calculating it because I automatically divided 128 by 8. But now I know.

But there is still something weird in it. If let's say a byte looked like this 00000001, and it goes through this inverse mask which I guess it is 00000000 using the XOR operation and I still have 00000001 and it is checked by the k in which this 1 is and it is in 1st place.

But at the end in the buffor it will be the same data which is 00000001, so why does the author added this SetPixel ? If I could as well just copy the whole array.

I don't know if what I said makes sense but basically why I just don't copy the array into the buffor. Because it is palced in the same order which means the first byte from the given array is the same as the first byte of the buffor.
 

MrChips

Joined Oct 2, 2009
34,809
When one is working with pixel graphics displays, one needs to be able to SET or CLEAR individual bits.
That is what this software does. Copying a byte does not perform SET or CLEAR on single bits.
 

Thread Starter

Xenon02

Joined Feb 24, 2021
504
That is what this software does. Copying a byte does not perform SET or CLEAR on single bits.
Oh why not ? If both the buffor and the array where the picture is, are the same (or is it that buffor and array with the picture don't have the same values inside ?).
Like I've said in an example of 00000001 that the first bit is also written in the buffor and the rest are 0 as well so we have the same byte like in the picture.
In the end buffor just sends through I2C I guess to the display the information from buffor. But since the buffor and the array with picture are the same then why not just write directly into the buffor.

Or maybe my example is incorrect ? I also thought that maybe it is done like that because SetPixel is universal for every display not only for arrays, and just because for arrays it works like that is just an coincidence, but it doesn't mean that why the byte isn't written already into the buffor. Because 00000001 is SET and RESET for both buffor and the array with picture.
 
Last edited:

MrChips

Joined Oct 2, 2009
34,809
You wish to alter the state of bit B0 and B0 alone.
You do not know the state of the remaining seven bits. You cannot assume that they are all zero. You must not alter the state of the remaining seven bits.

You must read the byte from the buffer, change one bit, and rewrite the byte into the buffer.
00000001 is a bit mask. It is not the data to be written to the buffer.
There are three possible boolean operations, OR, AND NOT, XOR.
 

Thread Starter

Xenon02

Joined Feb 24, 2021
504
You wish to alter the state of bit B0 and B0 alone.
You do not know the state of the remaining seven bits. You cannot assume that they are all zero. You must not alter the state of the remaining seven bits.
I can see in the code that I am changing only a single bit from the byte, but this single bit is from the array it provided.
The rest of the array 0 so this 0 is also putted into this buffer so in result we have 00000001 in both buffer and the array. If I wanted to change it from 00000001 to 00000010 then again it reads this first byte as 0 so it changes in the buffer from 1 to 0 and the second byte is changed from 0 to 1. in tesult we have again 00000010 in both buffer and the array. So I don't understand the difference in both when buffer just copy the bytes from array.


You must read the byte from the buffer, change one bit, and rewrite the byte into the buffer.
00000001 is a bit mask. It is not the data to be written to the buffer.
There are three possible boolean operations, OR, AND NOT, XOR.

(inverting_mask ^ bitmap[width*i + j]) & (1 << k) - this part reads the single byte in the bitmap/array we provided like in the example 00000001 it reads for k = 0 the first byte which is 1 as a color.


else if(color == OLED_COLOR_WHITE)
buffer[x + SCREEN_WIDTH * (y / 8)] |= (1 << (y % 8)); // Set bit responsible for pixel

So let's check here the bit is in the first place so x = 0 and y =0, it is passed in the buffer. We have then choosed the buffer which will be buffer[0] and it's content is ORed by the ~(1 << (y % 8) (which is just 00000001) so in result we have 00000000 OR 00000001 => 00000001 which is the same as the data provided at the beggining.

Same can go with 00000010 or other bytes. And the size of a buffer is the same as the size of a provided bitmap (pixture 128x64 = 1024).

That's why I see it as copy and paste into the buffer. So I still don't understand why the bitmap wasn't just pasted into the buffer or the bitmap itself acted as a buffer.
 

MrChips

Joined Oct 2, 2009
34,809
You are making the same mistake again. We don't need to know what is in the buffer data and we don't care.

Let us look at your example.
x = 0, y = 0. The 8-bit data is stored in buffer[0].
The data is xxxxxxxx. We don't care what is the data.

(1 << (y % 8)) gives 00000001. This is the bit mask. It is not data.

xxxxxxxx OR 00000001 = xxxxxxx1
This sets bit-0 to ONE.

xxxxxxxx AND NOT 00000001 = xxxxxxx0
This clears bit-0 to ZERO.
 

Thread Starter

Xenon02

Joined Feb 24, 2021
504
You are making the same mistake again. We don't need to know what is in the buffer data and we don't care.

Let us look at your example.
x = 0, y = 0. The 8-bit data is stored in buffer[0].
The data is xxxxxxxx. We don't care what is the data.

(1 << (y % 8)) gives 00000001. This is the bit mask. It is not data.

xxxxxxxx OR 00000001 = xxxxxxx1
This sets bit-0 to ONE.

xxxxxxxx AND NOT 00000001 = xxxxxxx0
This clears bit-0 to ZERO.
Mask is in inverting_mask. Which I don't know what is it's exact value. The bitmap[width*i + j] containts 00000001, and is XORed with inverting_mask which I guess was 0000000 I don't know because in the code it is : uint8_t inverting_mask = invert_color ? 0xFF : 0x00; Which doesn't say a lot.

Well I assumed that the mask is 0000000 XORed with bitmap[0] which is 00000001 the result is 00000001, k is equal 0 and is is ANDed with 00000001 so we have 1 ANDed 00000001 or rather 00000001 ANDed 00000001 Result 00000001.

How we have the coordinates which are x= 0 and y = 0 and the bool of 00000001 which is 1, so it is passed to the SetPixel.
buffer has xxxxxxxx. Now first bit will be 1 so now the buffer has xxxxxxx1, later the second bit is 0 xxxxxx01 and so on and so on because the color is 0 and the result is 00000001.

The buffer[0] has the same content as bitmap[0]. That's why I still don't get it why I just didn't pass the bitmap as a data not to the SetPixel function but rather already to the OLED because buffer sends it's data to the OLED, and it is the same as bitmap.

This function just takes time to make the same result as bitmap[0] had at the beggining. That makes no sense, if I changed the bitmap[0] into let's say 00000010 and scanned it and sent to SetPixel, then buffer[0] would have the same result which is 00000010, so as well I could just sent bitmap[0] straight to OLED. Instead of taking the time to make the same result but in buffer.

I don't get it why it is implemented, because it give the same result at the end.
 

Thread Starter

Xenon02

Joined Feb 24, 2021
504
I have no idea of what you are trying to say.
My post #10 says it all.

I understand what your post #10 says.
I am just trying to say that bitmap (the array that was the whole picture) has the same content as buffer. So why bother using a function that gives me the same result which is having the same content as bitmap ...

Like array[0] has 00000001 and buffer also has buffer[0] = 00000001. They are both the same.
You've mentioned :


(1 << (y % 8)) gives 00000001. This is the bit mask. It is not data.
It is the mask of where is "1" in this bitmap/array we have provided.

I've showed my point of view how the data is interpreted in post #11. And what I tried to say is why SetPixel is even used ? When both the provided array of pictures like array[0] is the same as the content of buffer[0] ? Why I say that check the post#11 and how I followed the provided 00000001 in bitmap[0] which is the first 8 pixels of the picture. The result ? buffer[0] is also 00000001.
 

MrChips

Joined Oct 2, 2009
34,809
void OLED_DrawBitmap(uint8_t x, uint8_t y, bool invert_color, uint8_t width, uint8_t height, const uint8_t* bitmap)
void OLED_SetPixel(uint8_t x, uint8_t y, bool color)

OLED_DrawBitmap( ) uses a bitmap as input and calls OLED_SetPixel( )
OLED_SetPixel( ) operates on buffer[ ]

Where and how is the bitmap defined? What is the purpose of the bitmap?
 

Thread Starter

Xenon02

Joined Feb 24, 2021
504
void OLED_DrawBitmap(uint8_t x, uint8_t y, bool invert_color, uint8_t width, uint8_t height, const uint8_t* bitmap)
void OLED_SetPixel(uint8_t x, uint8_t y, bool color)

OLED_DrawBitmap( ) uses a bitmap as input and calls OLED_SetPixel( )
OLED_SetPixel( ) operates on buffer[ ]

Where and how is the bitmap defined? What is the purpose of the bitmap?
Bitmap is an array that is provided by the programmer. You paste the whole array into the program and the picture is monochrome so it is black and the rest of the area is just blank, so black parts are 1 and the rest is 0. Like this example:


C:
const unsigned char miliohm 3 [] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x01, 0xFF, 0xFF, 0x80, 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, 0x1F, 0xFF, 0xFF, 0xF8, 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, 0xFF, 0xC0, 0x07, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0x00, 0x00, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFC, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x01, 0xF8, 0x1F, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x01, 0xFC, 0x3F, 0xC0, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x03, 0xCE, 0x79, 0xC0, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x03, 0x06, 0x60, 0xC0, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x06, 0x70, 0xE0, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x07, 0x06, 0xE0, 0x60, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x06, 0x07, 0xC0, 0x60, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0xF0, 0x06, 0x03, 0xC0, 0x70, 0x0F, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1F, 0xFE, 0xDE, 0x03, 0xC0, 0x75, 0xBF, 0xF8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFC, 0x03, 0xC0, 0x3F, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xFF, 0xF7, 0xFC, 0x01, 0xC0, 0x3F, 0xEF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0xC0, 0x00, 0x1C, 0x01, 0x80, 0x18, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0xC0, 0x00, 0x08, 0x21, 0x84, 0x30, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x08, 0x20, 0x84, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0xC0, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xF5, 0x55, 0x00, 0x70, 0x0E, 0x00, 0x56, 0xBF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x80, 0x70, 0x0E, 0x01, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0xF0, 0x0F, 0x01, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0xF1, 0x80, 0xF8, 0x1F, 0x01, 0x8F, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF9, 0xC0, 0xF8, 0x1F, 0x01, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF9, 0xC0, 0xD8, 0x1B, 0x83, 0x9F, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xC1, 0xDC, 0x1B, 0x83, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xE1, 0x9C, 0x39, 0x87, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x63, 0x8E, 0x39, 0xC7, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xFF, 0x8F, 0xF0, 0xFE, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3E, 0x07, 0xE0, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x94, 0x02, 0x80, 0x29, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x80, 0x00, 0x00, 0x01, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x0F, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xF8, 0x00, 0x00, 0x1F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFE, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0x03, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFA, 0xBF, 0xFE, 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, 0x01, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFC, 0x00, 0x00, 0x00, 0x00, 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, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0C, 0xD8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x0C, 0xD8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFB, 0x8C, 0xD8, 0x71, 0xB9, 0xB3, 0x80, 0x71, 0xC6, 0xCC, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xFF, 0xCC, 0xD9, 0xF9, 0xFD, 0xFF, 0xC1, 0xF7, 0xE7, 0xFE, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xCC, 0xCC, 0xD9, 0x9D, 0xDD, 0x98, 0xC1, 0x86, 0x76, 0x66, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xCC, 0xCC, 0xD9, 0x8D, 0x8D, 0x98, 0xC1, 0x86, 0x36, 0x66, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xCC, 0xCC, 0xD9, 0x9D, 0x8D, 0x98, 0xC9, 0x86, 0x76, 0x66, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xCC, 0xCC, 0xD9, 0xF9, 0x8D, 0x98, 0xDD, 0xF7, 0xE6, 0x66, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xCC, 0xCC, 0xD8, 0x71, 0x8D, 0x98, 0xC8, 0x71, 0xC6, 0x66, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
In which first byte is miliohm 3 [0] is 0x00 so it is 00000000 in bits.
In buffer it will also be buffer[0] = 0x00 => 00000000.
Or miliohm 3 [24] = 0x1F => 00011111, and this is passed to the OLED_DrawBitmap( ), and the sequence beggins :

inverting mask is probably 00000000 and is XORed with 00011111 the k is equal for now 0 for first iteration. So we have after the XOR 00011111 and it is ANDed with 00000001, so the result is we have now 00000001 the first bit and it is passed to OLED_SetPixel( ), as a bool color so it is now color = 1.

It is then passed to the buffer[24] as xxxxxxx1, then we begin the second iteration, similar thing which we just pass the XOR because it will be all the time the same, 00011111 and is ANDed with 00000010 result is 00000010, the bool of it is 1 so it is passed to the buffer and the result is buffer[24] = xxxxxx11.

I think it is visible that buffer[24] is equal miliohm 3 [24] which only makes no sense. Why this OLED_SetPixel( ) exist.
 

MrChips

Joined Oct 2, 2009
34,809
Without actually going to the library documentation, I would have to assume that the bitmap is width x height x 1 byte per pixel.
OLED_DrawBitmap assumes coloured pixels.
OLED_SetPixel assumes one bit per pixel and hence can only turn the pixel ON or OFF.
 

Thread Starter

Xenon02

Joined Feb 24, 2021
504
OLED_DrawBitmap contains in his instruction OLED_SetPixel. I understand what you mean, but it just didn't make sense at all for me when I read how OLED_DrawBitmap is constructed and that the provided array is the same as the buffer array which is passe to the OLED.

I am just confused with why the buffer and the array/bitmap array is the same. It only takes more time to do these functions. I mean I believe my confusion is visible here. And that maybe this SetPixel can be just skipped ? And just pass the bitmap straight to the OLED
 

MrChips

Joined Oct 2, 2009
34,809
I could not find any references to OLED_DrawBitmap( ) and OLED_SetPixel( ) on the internet.

As far as I can tell, you copied that code snippet from an Arduino forum and I cannot see where and how the bitmap was defined.
I will stick with my assumption that the bitmap is defined as a byte array 128 x 64 with 8-bit colour. This is not directly compatible with buffer[ ] which is a packed array of 128 x 64 bitmap of monochrome graphics. Hence they are not the same. You cannot pass the bitmap to the OLED. It must first be converted.
 

Thread Starter

Xenon02

Joined Feb 24, 2021
504
https://github.com/afiskon/stm32-ssd1306 - here is the first one in which (SetPixel is there as: ssd1306_DrawPixel). Similar code but it has an additional "if" statement in which it checks the height and the width just in case.

The code I stole from school so I don't know if the link will work but I guess not : https://gitlab-stud.elka.pw.edu.pl/...b/main/Core/Src/SSD1306/OLED.c?ref_type=heads I didn't change anything in it.

I've also thought that the data must be delivered differently to the OLED by using the buffor. But the bitmap must be monochrome. If it also works as you assumed for other colors then maybe in fact it might work but I don't know how the colored data are transfered into bytes. I know only that in 1 byte there are 8 bits each bit is 1 pixel so it is black or white.

But I believe you understand my confusion that buffor[0] and bitmap[0] or any other pair are literrally the same when it comes to the content, or rather do you think that I was right that the content of buffor[0] and bitmap[0] are the same from my example ?

PS. Also I think this library was primary thought about monochrome pictures. What I mean is that I have to change picture in my desktop from color into monochrome and then I can add it into my program/bitmap array so the bitmap array already has this monochrome picture. But as I said I don't know how the color pictures are stored.
 

MrChips

Joined Oct 2, 2009
34,809
Your mistake is in believing that buffor[ ] and bitmap[ ] are the same. They are not the same and they are not compatible.
buffor[ ] has one byte for each pixel. Each pixel can have any one of 256 colours.
bitmap[ ] has one byte for eight pixels. Each pixel is one bit and can have only two colours, white or black.
 
Top