Graphics arrayBuffer for 3-color ePaper display

Posted on
  • Hey guys,

    I'm trying to improve the handling of the GraphicsBuffer for my 3-color (white/black/red) ePaper display.

    So the display expects all pixels for black and all pixels for red to be send with a separate command. So the way it is now setup is, that I have created 2 separate GraphicBuffers of 1bpp each, e.g.

    var g_red=Graphics.createArrayBuffer(264, 176, 1, {msb: true});
    var g_black=Graphics.createArrayBuffer(264, 176, 1, {msb: true});
    

    Then I write both buffers to the ePaper using different commands:

    //write red
    writeCommand(CMD.DATA_START_TRANSMISSION­_1);
    for (let i=1;i<g_red.buffer.length;i++) writeData(g_red.buffer[i]);
    
    //write black
    writeCommand(CMD.DATA_START_TRANSMISSION­_2);
    for (let i=1;i<g_black.buffer.length;i++) writeData(g_black.buffer[i]);
    

    While this is working fine it bothers me, that I have 2 separate buffers to draw to. If I want to draw something in red, I have to use g_red.drawString(...) and for black g_black.drawString(...)

    What I was hoping for was to use a 2bpp buffer and then be able to use setColor do something like this:

    var g_both=Graphics.createArrayBuffer(264, 176, 2, {msb: true});
    
    //draw in red
    var g_both.setColor(red).drawString(...);
    
    //draw in black
    var g_both.setColor(black).drawString(...);
    

    But now, how do I transfer this to the ePaper. It is not as easy is sending every other byte of the buffer using one of the above commands right?

    When I try this, I get weird interlaced results:

    writeCommand(CMD.DATA_START_TRANSMISSION­_1);
    for (let i=0;i<g_both.buffer.length;i+=2) writeData(g_both.buffer[i]);
    
    writeCommand(CMD.DATA_START_TRANSMISSION­_2);
    for (let i=1;i<g_both.buffer.length;i+=2) writeData(g_both.buffer[i]);
    

    So if I understand this correctly: lets assume I want to only set the first 8 pixels of the display. When I want to set the first 2 pixels and the last 2 pixels to black, I would have to send the bit value 11000011 or 99 in decimal to the black buffer.

    Now if I want pixels 3-6 to be red, I would need to send bit value 00111100 or 60 to the red buffer.

    I cannot wrap my head around how this would work with a 2bpp graphics buffer though.

    Hope the above is not too confusing.

  • Use an C routine to extract into a transmit buffer... this is fast and lets you use the the Graphics class for Espruino style drawing and push out the buffer as is. Claiming contiguous memory should not be an issue... (see use of C in Efficiently moving things around in zig-zag Graphics buffer visualized w/ 24/32 bpp displays / neopixel strings. Using this technology you can trigger the update of the display anytime and it can run to its own beat. Used that technology in the same application context: drawing/writing to the Graphics object is event driven and updating the display/reading the Graphics object is event driven. Update you can trigger by time or at application flow specific points where you know that updating the display makes sense. I'm not sure if you use partial update... which I know was tried and shared in the forum, but I cannot recall final conclusions (your fourth color could be used for that - using a bit pattern for the white, red and black colors that share a bit - to determine what zone to update and clear it on update).

    Having the drawing and updating the display separated allows optimizing of automated update and at the same time on demand update as the application can control it (fire an event and move on, and update requests can be queued and skipped to do the least number of). Separation also makes it easy to exchange the displays type.

    If you are short on memory, doing it inplace? Not sure what you win, because transformation would have to happend before AND after transmission to display.

    @MaBe is one of the forum members who has extensive experience w/ 3-color ePaper displays. I'm sure he has his ideas too.

  • Hi - there might be something fancy you can do at https://graphics.stanford.edu/~seander/b­ithacks.html which will allow you to extract every odd/even bit. Either that or a 256-entry lookup table (to get 4 bits from the 8).

    Your other (much easier!) option is to use the 'drawImage' command to split out just the right bits for you. Normally it'd map 1:1 for 1/2 bit images, but if you specify a palette you can choose what color everything should map to:

    var g_both=Graphics.createArrayBuffer(264, 176, 2, {msb: true});
    g_both.setColor(2).drawLine(0,0,264,176)­;
    
    var img_both = g_both.asImage();
    var g_one=Graphics.createArrayBuffer(264, 176, 1, {msb: true});
    
    img_both.palette = new Uint16Array([0,0,1,1]);
    g_one.drawImage(img_both);
    // now g_one has bits set for colors 2,3
    img_both.palette = new Uint16Array([0,1,0,0]);
    g_one.drawImage(img_both);
    // now g_one has bits set for color 1 only
    
  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Graphics arrayBuffer for 3-color ePaper display

Posted by Avatar for Raik @Raik

Actions