{"id":4229,"date":"2020-09-02T20:00:18","date_gmt":"2020-09-02T18:00:18","guid":{"rendered":"https:\/\/msalamon.pl\/?p=4229"},"modified":"2025-12-27T16:15:31","modified_gmt":"2025-12-27T15:15:31","slug":"grayscale-oled-on-ssd1327-part-3","status":"publish","type":"post","link":"https:\/\/msalamon.pl\/en\/grayscale-oled-on-ssd1327-part-3\/","title":{"rendered":"Grayscale OLED on SSD1327, Part 3"},"content":{"rendered":"\n<p>I ended the last post about the <a href=\"https:\/\/sklep.msalamon.pl\/produkt\/wyswietlacz-oled-132-skala-szarosci-bialy\/?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=ssd1327&amp;utm_content=Text\">SSD1327 OLED<\/a> with the note that in order to use the GFX library, you need to introduce a few modifications to it. Today I\u2019ll deal with those modifications and we\u2019ll have full functionality of our <a href=\"https:\/\/sklep.msalamon.pl\/produkt\/wyswietlacz-oled-132-skala-szarosci-bialy\/?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=ssd1327&amp;utm_content=Text\">display with a 16-level grayscale<\/a>. At the end, we\u2019ll check what speeds can be achieved on such an <a href=\"https:\/\/sklep.msalamon.pl\/produkt\/wyswietlacz-oled-132-skala-szarosci-bialy\/?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=ssd1327&amp;utm_content=Text\">I\u00b2C OLED<\/a>. <\/p>\n\n\n\n<!--more-->\n\n\n\n<h1 class=\"wp-block-heading\"><figure><a href=\"https:\/\/sklep.msalamon.pl\/produkt\/wyswietlacz-oled-132-skala-szarosci-bialy\/?utm_source=blog&amp;utm_medium=banner&amp;utm_campaign=ssd1327\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/OLED-SSD1327-baner.jpg\" alt=\"\" width=\"1200\" height=\"400\" class=\"aligncenter wp-image-1606 size-full\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/OLED-SSD1327-baner.jpg 1200w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/OLED-SSD1327-baner-300x100.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/OLED-SSD1327-baner-1024x341.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/OLED-SSD1327-baner-768x256.jpg 768w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\"><\/a><\/figure><\/h1>\n\n\n\n<p class=\"has-text-align-center\"><span style=\"font-size: 24pt;\"><strong>Table of contents of the entire series about the SSD1327 OLED:<\/strong><\/span><\/p>\n\n\n\n<p class=\"has-text-align-center\"><strong><a href=\"http:\/\/msalamon.pl\/oled-ze-skala-szarosci-na-ssd1327-cz-1\/\">Grayscale OLED on SSD1327 part 1<\/a><br><\/strong><strong><a href=\"http:\/\/msalamon.pl\/oled-ze-skala-szarosci-na-ssd1327-cz-2\/\">Grayscale OLED on SSD1327 part 2<\/a><br><\/strong><strong><a href=\"http:\/\/msalamon.pl\/jak-przygotowac-obraz-dla-wyswietlacza-lcd-lub-tft\/\">How to prepare an image for an LCD or TFT display?<\/a><br><\/strong><strong><a href=\"http:\/\/msalamon.pl\/oled-ze-skala-szarosci-na-ssd1327-cz-3\/\">Grayscale OLED on SSD1327 part 3<\/a><\/strong><\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Modifying the GFX lib<\/h1>\n\n\n\n<p>The library that I pulled from another OLED \u2014 the one based on SSD1306 \u2014 works with images that use one-bit pixels. In that one, drawing a pixel was written in such a way that if it had the background color (which was passed as an argument), it could even not draw it, creating a transparent background.<\/p>\n\n\n\n<p>And in fact you could use it so that the picture would be drawn in a single color from the 0\u201315 range, but then why do we need such grayscale? We want to draw nice things, right? Things that will have depth and, for example, will render a nice GUI for us, right?<\/p>\n\n\n\n<p>That\u2019s why we need to slightly modify GFX BW so that it supports images saved in a 4-bit pixel format. Where should we introduce these changes? Exactly \u2014 in the image drawing function!<\/p>\n\n\n\n<p>First, we have to find which cell of the image array we want to assign to our buffer. You already know how to do this, because <a href=\"http:\/\/msalamon.pl\/oled-ze-skala-szarosci-na-ssd1327-cz-2\/\">I wrote about it in the previous post<\/a>. If we go through the image height as <strong>j<\/strong> and through the width as <strong>i<\/strong>, the cell in the array that interests us is <strong>SelectedCell = img[i\/2 + j*(w\/2)]<\/strong> \u2014 <strong>w<\/strong> is the image width that we pass as an argument.<\/p>\n\n\n\n<p>As a side note, it would be nice to modify image drawing so that the function itself would read the height and width from the image header that <a href=\"http:\/\/msalamon.pl\/jak-przygotowac-obraz-dla-wyswietlacza-lcd-lub-tft\/\">Img2Lcd generates, which I wrote about in this post<\/a>. Maybe you\u2019ll fork my project on GitHub and write something like that? \ud83d\ude42<\/p>\n\n\n\n<p>Back to the main topic\u2026 having the selected cell, we now need to assign the appropriate pixel value to our pixel in the RAM buffer for the displayed image. In one byte we only have two pixels to choose from. In the previous post we also noticed that even ones are always on the same side of the byte. We need to use that!<\/p>\n\n\n\n<p>The procedure for selecting the appropriate pixel value and writing it into the <a href=\"https:\/\/sklep.msalamon.pl\/produkt\/wyswietlacz-oled-132-skala-szarosci-bialy\/?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=ssd1327&amp;utm_content=Text\">OLED<\/a> RAM looks like this.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">if(i % 2)\n{\n\tSelectedCell &amp;amp;= 0x0F;\n}\nelse\n{\n\tSelectedCell &amp;gt;&amp;gt;= 4;\n}\nGFX_DrawPixel(x+i, y+j, SelectedCell);<\/pre>\n\n\n\n<p>Looks simple, right? That\u2019s really it! So the entire function for drawing an image into the buffer looks like this.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">void GFX_Image(int x, int y, const uint8_t *img, uint8_t w, uint8_t h)\n{\n\tuint8_t i, j;\n\tuint8_t SelectedCell;\n\n\tfor(j = 0; j &amp;lt; h; j++)\n\t{\n\t\tfor(i = 0; i &amp;lt; w; i++)\n\t\t{\n\t\t\tSelectedCell = img[i\/2 + j*(w\/2)];\n\n\t\t\t if(i % 2)\n\t\t\t {\n\t\t\t\t SelectedCell &amp;amp;= 0x0F;\n\t\t\t }\n\t\t\t else\n\t\t\t {\n\t\t\t\t SelectedCell &amp;gt;&amp;gt;= 4;\n\t\t\t }\n\n\t\t\tGFX_DrawPixel(x+i, y+j, SelectedCell);\n\t\t}\n\t}\n}<\/pre>\n\n\n\n<p>I also made a few minor changes like the library name and so on, so that it matches <a href=\"https:\/\/sklep.msalamon.pl\/produkt\/wyswietlacz-oled-132-skala-szarosci-bialy\/?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=ssd1327&amp;utm_content=Text\">this display<\/a> nicely in terms of naming. The result? Beautiful images with color depth \ud83d\ude42<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><figure><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/IMG_0171-2-scaled.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/IMG_0171-2-300x300.jpg\" alt=\"\" width=\"300\" height=\"300\" class=\"wp-image-1656 size-medium aligncenter\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/IMG_0171-2-300x300.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/IMG_0171-2-1024x1024.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/IMG_0171-2-150x150.jpg 150w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/IMG_0171-2-768x768.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/IMG_0171-2-1536x1536.jpg 1536w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/IMG_0171-2-2048x2048.jpg 2048w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\"><\/a><\/figure> <figure><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/IMG_0172-2-scaled.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/IMG_0172-2-300x300.jpg\" alt=\"\" width=\"300\" height=\"300\" class=\"wp-image-1657 size-medium aligncenter\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/IMG_0172-2-300x300.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/IMG_0172-2-1024x1024.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/IMG_0172-2-150x150.jpg 150w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/IMG_0172-2-768x768.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/IMG_0172-2-1536x1536.jpg 1536w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/IMG_0172-2-2048x2048.jpg 2048w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\"><\/a><\/figure> <figure><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/IMG_0174-2-scaled.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/IMG_0174-2-300x300.jpg\" alt=\"\" width=\"300\" height=\"300\" class=\"wp-image-1658 size-medium aligncenter\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/IMG_0174-2-300x300.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/IMG_0174-2-1024x1024.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/IMG_0174-2-150x150.jpg 150w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/IMG_0174-2-768x768.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/IMG_0174-2-1536x1536.jpg 1536w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/IMG_0174-2-2048x2048.jpg 2048w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\"><\/a><\/figure>How fast does it run?<\/h2>\n\n\n\n<p>We have much more data here than when sending to a monochrome display. Not only is the resolution slightly higher, but each pixel also contains 4x more data. So can we achieve satisfactory results over I\u00b2C? <a href=\"http:\/\/msalamon.pl\/oled-ze-skala-szarosci-na-ssd1327-cz-1\/\">In the first part I did some theoretical calculations<\/a>. What does it look like in practice? Let\u2019s check!<\/p>\n\n\n\n<p><strong>The whole thing at a 100 kHz<\/strong> clock, i.e., copying an image that fills the entire area of the <a href=\"https:\/\/sklep.msalamon.pl\/produkt\/wyswietlacz-oled-132-skala-szarosci-bialy\/?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=ssd1327&amp;utm_content=Text\">OLED<\/a> and sending it to the controller, takes <strong>as much as 573 ms<\/strong>. An eternity!<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_refresh_100k.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"1920\" height=\"218\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_refresh_100k.jpg\" alt=\"\" class=\"wp-image-1659\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_refresh_100k.jpg 1920w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_refresh_100k-300x34.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_refresh_100k-1024x116.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_refresh_100k-768x87.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_refresh_100k-1536x174.jpg 1536w\" sizes=\"auto, (max-width: 1920px) 100vw, 1920px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p>Let\u2019s break it down. Copying the image from the array to the <a href=\"https:\/\/sklep.msalamon.pl\/produkt\/wyswietlacz-oled-132-skala-szarosci-bialy\/?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=ssd1327&amp;utm_content=Text\">OLED<\/a> buffer itself is just under 23 ms. Better, but still a lot, right? Remember that this copy uses the DrawPixel function and is not a blind cell-by-cell copy. This introduces some calculations that could probably be partially avoided.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_copy_image_100k.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"1920\" height=\"226\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_copy_image_100k.jpg\" alt=\"\" class=\"wp-image-1661\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_copy_image_100k.jpg 1920w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_copy_image_100k-300x35.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_copy_image_100k-1024x121.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_copy_image_100k-768x90.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_copy_image_100k-1536x181.jpg 1536w\" sizes=\"auto, (max-width: 1920px) 100vw, 1920px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>It turns out that sending is insanely long, which you can see in the waveforms. It takes about 550 ms.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_transfer_100k.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"1920\" height=\"222\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_transfer_100k.jpg\" alt=\"\" class=\"wp-image-1660\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_transfer_100k.jpg 1920w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_transfer_100k-300x35.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_transfer_100k-1024x118.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_transfer_100k-768x89.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_transfer_100k-1536x178.jpg 1536w\" sizes=\"auto, (max-width: 1920px) 100vw, 1920px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>Working at 100 kHz I\u00b2C means you won\u2019t get more than 2 FPS. Embarrassing! <strong>Let\u2019s move to 400 kHz<\/strong>, which is the maximum this <a href=\"https:\/\/sklep.msalamon.pl\/produkt\/wyswietlacz-oled-132-skala-szarosci-bialy\/?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=ssd1327&amp;utm_content=Text\">OLED<\/a> can theoretically accept. In theory, it should be 4 times better.<\/p>\n\n\n\n<p><strong>Copying the image + transfer is 182 ms<\/strong>. That would be about 5.5 FPS. Still poor\u2026 you\u2019ll see the redraw during full-screen animations.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_refresh_400k.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"1920\" height=\"222\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_refresh_400k.jpg\" alt=\"\" class=\"wp-image-1662\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_refresh_400k.jpg 1920w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_refresh_400k-300x35.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_refresh_400k-1024x118.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_refresh_400k-768x89.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_refresh_400k-1536x178.jpg 1536w\" sizes=\"auto, (max-width: 1920px) 100vw, 1920px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p>Copying the image should take the same amount of time, i.e., ~23 ms. Nothing should change in this area.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_copy_image_400k.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"1920\" height=\"220\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_copy_image_400k.jpg\" alt=\"\" class=\"wp-image-1663\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_copy_image_400k.jpg 1920w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_copy_image_400k-300x34.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_copy_image_400k-1024x117.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_copy_image_400k-768x88.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_copy_image_400k-1536x176.jpg 1536w\" sizes=\"auto, (max-width: 1920px) 100vw, 1920px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>However, <strong>transfer to the OLED is 159 ms<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><figure><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_transfer_400k.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_transfer_400k.jpg\" alt=\"\" width=\"1920\" height=\"224\" class=\"aligncenter size-full wp-image-1664\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_transfer_400k.jpg 1920w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_transfer_400k-300x35.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_transfer_400k-1024x119.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_transfer_400k-768x90.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/08\/ssd1327_full_transfer_400k-1536x179.jpg 1536w\" sizes=\"auto, (max-width: 1920px) 100vw, 1920px\"><\/a><\/figure>Acceleration possibilities.<\/h2>\n\n\n\n<p>You can try to overclock I\u00b2C even more. <a href=\"https:\/\/sklep.msalamon.pl\/produkt\/wyswietlacz-oled-132-skala-szarosci-bialy\/?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=ssd1327&amp;utm_content=Text\">SSD1327<\/a> should easily run at 1 MHz just like the SSD1306. But that goes beyond the documentation, so it\u2019s living on the edge.<\/p>\n\n\n\n<p>A much better solution would be to connect <a href=\"https:\/\/sklep.msalamon.pl\/produkt\/wyswietlacz-oled-132-skala-szarosci-bialy\/?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=ssd1327&amp;utm_content=Text\">the same OLED<\/a> via SPI. There you can go up to 10 MHz! That is truly suitable for a fast and unnoticeable image swap.<\/p>\n\n\n\n<p>But\u2026 my model doesn\u2019t have SPI on the PCB and doesn\u2019t allow changing the interface with any jumpers. You\u2019d need to look for an <a href=\"https:\/\/sklep.msalamon.pl\/produkt\/wyswietlacz-oled-132-skala-szarosci-bialy\/?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=ssd1327&amp;utm_content=Text\">OLED<\/a> version with SPI, and that can be hard to find. Out of ready-made PCB modules, I think only Waveshare has it.<\/p>\n\n\n\n<p>You can make your own PCB! Take the bare <a href=\"https:\/\/sklep.msalamon.pl\/produkt\/wyswietlacz-oled-132-skala-szarosci-bialy\/?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=ssd1327&amp;utm_content=Text\">OLED<\/a> module and connect the jumpers appropriately to select SPI. This also involves designing a converter for the panel supply, so it\u2019s rather for more advanced people.<\/p>\n\n\n\n<p>If you stick with I\u00b2C, there\u2019s nothing else to do than develop an interface that doesn\u2019t have fast animations. After all, you don\u2019t always need to refresh all pixels, and redrawing the same ones won\u2019t be visible.<\/p>\n\n\n\n<p>Another way could be to give up buffering and draw only in areas that change. With such a controller you can limit the drawing area in the controller, and then simply send pixels. There are quite a few possibilities!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/sklep.msalamon.pl\/kategoria-produktu\/dev-boardy\/stm32-nucleo\/?utm_source=blog&amp;utm_medium=banner&amp;utm_campaign=ssd1327\"><img loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"400\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner.jpg\" alt=\"\" class=\"wp-image-1593\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner.jpg 1200w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner-300x100.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner-1024x341.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner-768x256.jpg 768w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>Reworking the GFX library turned out to be ridiculously simple! Now you can easily throw beautiful images onto the OLED \ud83d\ude09<\/p>\n\n\n\n<p>The speed is worse\u2026 Unfortunately, you have to limit yourself to slowly changing content. However, from what I see on the Internet, most projects tend to have slowly changing GUIs anyway \ud83d\ude42<\/p>\n\n\n\n<p><strong>If you liked the article, buy something from me!<span>&nbsp;<\/span><img decoding=\"async\" draggable=\"false\" role=\"img\" class=\"emoji\" alt=\"?\" src=\"https:\/\/s.w.org\/images\/core\/emoji\/13.0.0\/svg\/1f642.svg\"><span>&nbsp;<\/span><a href=\"https:\/\/sklep.msalamon.pl\/?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=nrf24&amp;utm_content=Text\">https:\/\/sklep.msalamon.pl\/<\/a><\/strong><\/p>\n\n\n\n<p>The full project together with the library can be found as usual on my GitHub:<span>&nbsp;<\/span><a href=\"https:\/\/github.com\/lamik\/OLED_SSD1327_STM32_HAL\" target=\"_blank\" rel=\"noopener\">LINK<\/a><\/p>\n\n\n\n<p><span>If you noticed an error, disagree with something, would like to add something important, or simply feel like you\u2019d like to discuss this topic, write a comment. Remember that the discussion should be polite and follow the rules of the Polish language.<\/span><\/p>\n\n\n\n<p class=\"has-text-align-center\"><span style=\"font-size: 24pt;\"><strong>Table of contents of the entire series about the SSD1327 OLED:<\/strong><\/span><\/p>\n\n\n\n<p class=\"has-text-align-center\"><strong><a href=\"http:\/\/msalamon.pl\/oled-ze-skala-szarosci-na-ssd1327-cz-1\/\">Grayscale OLED on SSD1327 part 1<\/a><br><\/strong><strong><a href=\"http:\/\/msalamon.pl\/oled-ze-skala-szarosci-na-ssd1327-cz-2\/\">Grayscale OLED on SSD1327 part 2<\/a><br><\/strong><strong><a href=\"http:\/\/msalamon.pl\/jak-przygotowac-obraz-dla-wyswietlacza-lcd-lub-tft\/\">How to prepare an image for an LCD or TFT display?<\/a><br><\/strong><strong><a href=\"http:\/\/msalamon.pl\/oled-ze-skala-szarosci-na-ssd1327-cz-3\/\">Grayscale OLED on SSD1327 part 3<\/a><\/strong><\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;4229&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;0&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;0&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;0&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;0\\\/5 - (0 votes)&quot;,&quot;size&quot;:&quot;24&quot;,&quot;title&quot;:&quot;Grayscale OLED on SSD1327, Part 3&quot;,&quot;width&quot;:&quot;0&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} - ({count} {votes})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 0px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 19.2px;\">\n            <span class=\"kksr-muted\"><\/span>\n    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>I ended the last post about the SSD1327 OLED with the note that in order to use the GFX library, you need to introduce a few modifications to it. Today I\u2019ll deal with those modifications and we\u2019ll have full functionality of our display with a 16-level grayscale. At the end, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3497,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[160],"tags":[176,174],"class_list":["post-4229","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-stm32","tag-programming","tag-stm32"],"_links":{"self":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts\/4229","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/comments?post=4229"}],"version-history":[{"count":3,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts\/4229\/revisions"}],"predecessor-version":[{"id":4232,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts\/4229\/revisions\/4232"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/media\/3497"}],"wp:attachment":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/media?parent=4229"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/categories?post=4229"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/tags?post=4229"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}