The EPD screen is called E-paper because once it is finished "printing", it will retain the content even if the power is disconnected. So as you can imagine, when we actually driving the EPD screens, we have three different operations: write (encoded 0b01), wipe (encoded 0b10), leave it as is (encoded 0b00). The first operation will turn a white pixel into black, the second will turn a black pixel into white and the third will do nothing. More about these operations later. But there is a big drawback of EPD displays, that is the EPD pixel need some time to turn itself from black to white or from white to black. And that time is usually more than 300ms so we say EPD have a long response time.
However, the EPD is usually refreshed at a higher frame rate, like 60Hz. So you can see under 60Hz setting, the pixel won't be able to fully turn around in one frame. So there are two ways, one if lower down the refresh rate, aka keeping one frame longer, another is adding more frames. For an example, if your screen have a response time of 1/3s(333ms), you can either lower the frame rate to 3Hz or send 20 same frames under 60Hz. My driver used the later method. The reason is that when using the first method, you can actually see the screen refreshed up to down since the data is being sent in that speed. The second method (more frames) would not have this effect. You see the whole screen get refreshed together. (though actually still up to down but you can't see) So here it the full idea: assume we start from a white screen which have a resolution of 2px * 1px, and we want it to display something like, one light pixel followed by a dark one: [ *]. So for the first pixel, it's already white (we start from white), so send the third operation (leave it as is) to the screen. For the second pixel, it need to be black, so we send the first operation (write) to the screen. And that’s one frame, we are running under 60Hz, so send 20 times. And we should get would we hoped.
But what if you stop driving a pixel before it totally turned around? Like, we send only 10 frames in the last example. The answer is that it would stay gray. And that's the fundamental of grayscale display on EPD panels. By controlling the driving time, we can create 4 shades or even 16 shades of gray. My driver used 4bpp(16shades) mode for better image quality, but if you can understand the principle, you can easily modify it to 4 shades or maybe 32 shades. Okay here is the thing. In 4bpp mode, there are 16 shades of gray. Let's continue with the assumption we made about the response time, 1/3s and begin with a white screen. If we evenly divide 1/3s into 15 slices, which is 1/45s each. So then we turn the frame rate to 45Hz, so one frame is 1/45s. For the pixel that's black, it’s obvious we want to send “write” command to the screen for 15frames, and it would turn black. For the pixel that’s white, just send “leave as is” in all 16 frames, it would leave white. That’s essentially the same as before. But if we want it to be the first shade of gray (which is, 1/15 of the brightness, note that 15/15 is black and 0/15 is white), simply send “write” in the first frame and “leave as is” in all other frames. So, the fourth shade of gray would be 4 frames of “write” plus 11 frames of “leave as is”. So what if we want 32 shades of gray? Adjust the frame rate to 93Hz and we are almost ready to go.
Unfortunately, things are not that easy. First of all, our STM32 software driving method is unable to achieve a refresh rate of 60Hz. Actually it can do only about 12Hz. So 4 frames is enough to drive the pixel from black to white or from white to black. It would be fine if I stick with monochrome mode or 2bpp (4-level) grayscale mode. But what if I want to do 4bpp mode, I have to use some tricks. Normally, the MCU send the data to source driver of...
Read more »