Sunday, October 29, 2017

Fast partial refresh on 4.2" E-paper display from Waveshare / Good Display



Google Drive link with Arduino firmware used in this project: 
https://drive.google.com/drive/folders/0B4YXWiqYWB99UmRYQi1qdXJIVFk?resourcekey=0-dqXf8rrfVykfI9H53piG9A&usp=sharing


I bought the Waveshare devices on Aliexpress: https://www.aliexpress.com/item/400x300-4-2inch-E-Ink-display-module-SPI-Without-backlight-Compatible-with-variuous-board-Ultra-low/32827172081.html


Datasheet with the 42-byte LUT format used in the 4.2" display, but not the exact correct part.
https://www.smart-prototyping.com/image/data/9_Modules/EinkDisplay/GDEW0154T8/IL0373.pdf


Interesting thread with other folks experimenting with LUTs on the 2.7" display.
https://github.com/olikraus/u8g2/issues/318


Waveshare (distributor) datasheet
https://www.waveshare.com/w/upload/6/6a/4.2inch-e-paper-specification.pdf



Good Display (manufacturer) datasheet
http://www.good-display.com/products_detail/productId=321.html

Waveform "theory" with class 7-5-7 pulse sequence:
http://www.multicomponent.se/sub_group_files/13dae3f428be3929dc13fed1f79c5e40.pdf

My favorite microcontroller dev board, the Teensy: https://www.pjrc.com/teensy/

The new awesome 5-series oscilloscope from Tek: https://www.tek.com/oscilloscope/5-series-mso-mixed-signal-oscilloscope


62 comments:

  1. A very cool video and it was really interesting seeing the details you've managed to dig up on how this kit works.

    You mention that the epd code is "Public Domain", but the code from waveshare's wiki has only readmes with licenses and they're "All Rights Reserved", which means that you don't even have rights to download it from their website. I'd say it was a license fail since I doubt very much they intend to distribute undistributable code.

    It would be hard to make a commercial project without being invited into copyright infringement with their products though. Still cool tech though.

    ReplyDelete
    Replies
    1. Thanks! The header of the .cpp files says the code is completely free to use as long as the header is maintained in the copies. I think some folks write licenses without knowing the exact details, but it seems they want to give the code away as long as they are credited as the source.

      Delete
  2. Excellent video with helpful information. Thank you!

    Did you produce your video with the code you provide for download?

    After some syntax fixes I get only white screen and some short flashes.

    ReplyDelete
    Replies
    1. Thanks! Yes, the code is the same as shown in the video. What syntax errors did you encounter? I'm using the Teensy 3.x dev board, which is capable of pretty high speed SPI. I have it set to 18MHz in epdif.cpp Try turning it way down (start at 1 MHz)

      Delete
    2. I have no Teensy, and not installed Arduino package for Teensy 3.x (would need to search for, seems not part of the unofficial list, only 2.x found).

      elapsedMillis may be a type name for Teensy?
      digitalWriteFast seems to be a method for Teensy.

      I reduced SPI speed to 4MHz, which is in the specs range and works fine with my examples.

      I get only white screen, and the typical full refresh black/white flashes.

      Jean-Marc Zingg

      Delete
    3. Yes, elapsedMillis and digitalWriteFast are part of Teensyduino. You can simply change digitalWriteFast to digitalWrite, and remove elapsedMillis. Does the stock Waveshare firmware work with your display? Are you using the black-and-white 4.2"? Do you have enough RAM for a full 400x300 framebuffer? If not, you'll want to construct a smaller framebuffer, and only update a part of the display's RAM at a time (like the original Waveshare firmware).

      Delete
  3. Yes to all your questions.
    Currently I have no time to analyze why it does not work for me.

    Have you repeated your test, e.g. after complete power switch off?
    I had seen some strange effects with partial update, also with the Waveshare code.

    ReplyDelete
  4. Hi Ben,
    great work! It seem sto me that your LUT only are setup for BW and not for BWR (with red color) mode?
    Have you tried it with the BWR mode too?
    Thanks and best regards,
    Erich

    ReplyDelete
    Replies
    1. I have made quicker LUTs (by trial and error and of course based on this post) for 2.7inch Waveshare BWR. I had the same problem as you had, just because of the red color. It is seems that the last lines of LUT tables are strictly to cope with red colors refresh.
      The modification is not so spectacular and sophisticated as Ben's, but still the B&W update is like 5-10 times quicker, for red die it is 2-3 times quicker (but still takes more time).
      Take a look here: https://github.com/pskowronek/epaper-clock-and-more/blob/master/epds/epd2in7b_fast_lut.py and compare it with https://github.com/pskowronek/epaper-clock-and-more/blob/master/epds/epd2in7b.py.

      Delete
    2. Strangely enough (or not) those display's controller ICs, EK79652 or EK79651AB have similar opCodes (both function and offset matching) to those found in the UC8151 powering 2.9" ePaper BWR/Y displays. Did you make any progress on the matter ? I'd bet there are some undocumented opcodes in the [0x25 to 0x2F] range.

      Delete
  5. Same question here, I'm interested in enhancing my BWR EPD refresh/parital update rate.

    Chaps

    ReplyDelete
  6. Yeah, after some fixes it works for me on arduino due
    https://www.dropbox.com/sh/0idofmjyijztm90/AAAx_yMcN4vur0c5eMOkxvkca?dl=0
    Thanks :)

    ReplyDelete
  7. Thank you so much! It's hard to find information on these things that isn't in broken English or Chinese!

    It's not just me! I've had to compare like 4+ documents with conflicting hardware layouts and software commands, complemented by bug-filled demo code. I'm a novice at this, and I thought I just didn't know the tech properly; but finding out that you had problems with getting information makes this feel a lot less painful.

    I cannot express how important your post is to me, because trying to get this to work for the last 5+ months at my job has been a nightmare!

    I'd really love to be able to ask you more about what you learned about the terminology, like bypass RAM, temperature variation, etc., but I'm not sure of the best way to contact you or if you'd even like to be bothered with it.

    ReplyDelete
  8. I may be missing something, but when doing "quick" refresh why do we need to make any transition for same colour? Is there any way to send "noop" pixel. Also did you manage to control 3 color display in this way? I'm very interested in "partial" updates on epd, especialy on the 3 color epd. Also if I understand well, this code should be applicable for 7.5 display of the same company, right?

    ReplyDelete
  9. Does this kind of "hack" could be applied to the 2.9 inch black and white Waveshare display version?

    Thank fouy for such a nice video and explanation

    ReplyDelete
  10. Awesome article but could someone help a newbie connect up his Teensy 3.2. I cannot get it to work and I suspect my connections being incorrect. Ben could you or anyone post the pin connections required from the Waveshare to the Teensy? Thanks :)

    ReplyDelete
    Replies
    1. It's ok, I've fixed it now.

      Delete
    2. Hello,
      Can i know how please? and wich example sketch u use?
      i have one waveshare 2.9 and one teensy.

      Regards,

      Delete
    3. I am also having problems with the wiring, could someone post the pin outs for the Teensy 3.2

      Thanks
      B

      Delete
  11. Hello! I wanted to tell you that you made a great piece of work here.

    I was wondering if you made some test with the epaper 2.9inch display regarding modifying the refresh rate. Did you get some progress with the epaper 2.9inch display? I'm currently working on a project and I require to get the fastest refresh rate as possible

    ReplyDelete
  12. Hello Ben, thank you for the informative video. I was wondering if you could give me some advice. I am working on a Data Acquisition system for my Senior Design project with my two other classmates, and we are currently trying to get our E-paper displays to work with our Ardunio. What we are having trouble with, is the refresh rate is very slow, updating the screen every four seconds. Is there a simplar way to update it with your data file for e-paper to make it refresh as much as 3 times a second? I Would love to hear back from you if you can, sir. Thank you for the video and the time to read my comment. Have a nice day!

    ReplyDelete
  13. @Shadowkeyblade7: Watch the video. You "just" need to change the LUTs for faster updates. You can also look at his code in the google drive share that he linked above.

    @Ben: Do you have a working link to the waveform theory with the class 7-5-7 pulse sequence? The current one just redirects me to their main index.

    ReplyDelete
  14. Hi Ben, very impresive work!, i have a just a question, i have a waveshare 7.5 inch display from waveshare.

    https://www.waveshare.com/7.5inch-e-Paper-HAT.htm



    i was looking on the firmware version for this LUTs arrays, but it seems as this display (7.5inchs) don´t work in this way, im trying to find on the specification sheet, what register or command set the this Image Upgrade times, could you took a look around this?
    https://www.waveshare.com/w/upload/b/b6/7.5inch-e-paper-specification.pdf

    fory any ideas or tips i will be very gratefu.

    Best regards.

    ReplyDelete
  15. Ben. Thanks for the excellent article. I learned a lot and this helped me on my partial refresh adventure.

    I modified the LUTs to double the refresh rate on the Waveshare 4.2 inch and ran it about 10,000 cycles. The bottom line, is that I have some burn-in / ghosting. I have run it through about 5,000 cycles of unmodified LUT / slow refresh to hopefully get the charges equilibrated in the display. The display has become better, but still has some ghosting.

    The LUTs I used basically called on the last two signal patterns for each w/w, b/w, w/b, b/b pattern.

    Example LUT below: (orig. and modified/quick):

    lut_vcom0 = [
    0x00, 0x17, 0x00, 0x00, 0x00, 0x02,
    0x00, 0x17, 0x17, 0x00, 0x00, 0x02,
    0x00, 0x0A, 0x01, 0x00, 0x00, 0x01,
    0x00, 0x0E, 0x0E, 0x00, 0x00, 0x02,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    ]

    lut_vcom0_quick = [
    0x00, 0x0A, 0x01, 0x00, 0x00, 0x01,
    0x00, 0x0E, 0x0E, 0x00, 0x00, 0x02,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    ]

    Hopefully this will help your project.

    I'm moving on to test other panels. I'm especially interested in the "low temperature" panels. Since these likely use liquids other than water and may offer less charge memory than the aqueous systems.

    Regards.

    ReplyDelete
  16. Would the refresh work as well with a larger font, using the display as a speed indicator for example,

    ReplyDelete
  17. Hi Ben, Thanks for a really excellent blog on getting e paper to work at super speeds. I have a quick question: fonts? Do you know what was used to generate the 4 or 5 fonts in the epd library? Thanks in advance.

    ReplyDelete
  18. Hey Ben, im having a problem using this on a Teensy LC. have you tried using this with the LC model? if so did you run into any problems?

    Thanks!

    PS: it seems to just hardware crash right after i upload the sketch.

    ReplyDelete
  19. Just modified a raspberry pi version of Waveshare firmware with Ben's lookup table. Works great now without flashing.
    Does leave a ghost image after a short while, but minor and after 11 hour test for an odometer display, just running the original LUTs with software for just a white screen clears all ghosting after about 5 hours! Raspberry version does not seem to havepartial update capability in firmware so update is about 5 seconds, as far as I can see this is largely the time in firmware to get the framebuffer to load into display.

    Peter

    ReplyDelete
    Replies
    1. Hi, could you share your library? many thanks

      Delete
    2. Hello Peter,

      I would also be very interested in peeking at your Pi library if you would be so kind to share it. I'm currently embarking on a project that would greatly benefit from comparing and learning from what you have done so far.

      Thanks!

      Delete
    3. +1 :)

      I am currently playing with 2.7" black-red-white e-display attached to Raspberry Pi Zero W and using Python. I am looking for a way to enable partial display for my hobby project and would also be happy to look into your approach. I was planning to port Ben's Arduino/CPP code to Raspberry/Python, but run into basic problems: I don't know the LUT structure and unmodified LUTs from my 2.7" display driver are different from Ben's unmodified LUTs. Any hint?

      Delete
  20. Guys, (Sean & Redexp)

    I am quite happy for you to have copies of my programmes and modified Waveshare programs. However being a novice at this sort of thing I have no idea how to get them to you via this blog and I do not do anything else other than email! I can of course just cut and paste the files here if that would work.

    Progress to date.
    I have given up refreshing the display to remove ghosting. after running in my "immediate update" mode for several days, the ghosting no longer clears completely, however in use all is OK. so long as the display is powered it cleanly switches between frames with no residual ghosting. Ghosting is only apparent, sometimes, after de-powering the Raspberry Pi. I assume it is due to how the dc power decays at power down, leaving the display in a half way mode.
    Currently all seems OK using a Raspberry 1B but I cannot get the GPSD to generate a speed number using a Pi Zero. Guess I need to set some SPIs or serial modes in the Zero hardware.
    Had a bit of a disaster yesterday, 3D printed a case for the display, it was a bit of a tight fit. Screwing the display down I heard a couple small ticks. On powering up the display it appears internally broken on some connections as it now updates only every other line in the upper part. Still OK for testing, but Ii have ordered another display.
    Let me know if I can justpaste my py programs here.

    ReplyDelete
    Replies
    1. Hi, could you kindly send your code to waveshareraspberrypicode@yopmail.com, which is a public temporary email inbox. So we can all share your good solution? Many thanks!

      Delete
    2. Sean,

      Please let me know once mr5k (Peter) has sent you the code. Then I can either setup a public inbox as well or maybe you can share it via a cloud service, up to you.

      Otherwise, I'll be experimenting on my own with the C code to improve partial refresh updates. I have not made much progress as of yet, but this project is still new as I just got the hardware in and started to experiment.

      Have a Happy Holiday,
      Mike

      Delete
  21. Sean,
    OK, will do after Xmas

    cheers

    Peter

    ReplyDelete
  22. Sean & Mike,
    OK I have emaile a zip file of my code to the yopmail.com website.

    Happy Christmas

    Peter

    ReplyDelete
    Replies
    1. Hey,

      I'm unable to download the attachment from the yopmail address, but I did send you an email myself.

      Please send be a reply to my email when you have a chance with your code as an attachment.

      Thanks and sorry to keep bugging you.

      Delete
    2. Regarding sharnig the files: you could upload the zip with files to your google drive (the one, that Google makes available to you with gmail.com account) and publish here the view-only access link to this zip.
      You can also remove the file and/or the link later on should you wish so.

      Delete
  23. This comment has been removed by the author.

    ReplyDelete
  24. Sean & Mike,

    The GPS-Speedo5 program seems to be a bit messed up.
    While the Waveshare part is fine, my attempt to read speed from the GPSD part fails. I tested statically and got low random speeds that I assumed were just the GPS uncertainty. however having now tested it on the move I get nonsensical results. Wil look again at ther code and/or my GPS module to see wherre I have screwed up !!!

    cheers

    Peter

    ReplyDelete
  25. Sean & Mike
    OK, I have now established that the GPS speed issue is not me but an anomoly in GPSD. All is OK if I start the pi manually then run my GPS Speedo, however if I autostart my GPS speedo program at boot GPSD does not fully startup and causes all sorts of errors.
    Looking through variuos threads I hope to have an "autostart" solution soon.

    cheers

    Peter

    ReplyDelete
  26. Sean & Mike
    Am still having problems with GPS, both GPSD and just reading serial NMEA strings via a USB GPS. Am beginning to think that maybe the Waveshare "firmware" is somehow afffecting the TTY USB0 pi interface. ( The GPS via USB works fine on an android)
    Currently abandoning this route and will try a bluetooth GPS with waveshare on a pi zero w, using bluetooth interface.

    Please let me know if you still have any interest in my project, if not I will stop posting here.


    cheers

    Peter

    ReplyDelete
  27. Hi Ben, I downloaded the code for epaper 4.2 and arduino. If I want to translate the program there are many errors. I use Arduino 1.8.7 and the STM32 board. Can you help me? Thank you in advance. Jiri

    ReplyDelete
  28. OK, All sorted. Not a Waveshare problem.
    But due to length of loop to refresh display, the TTYUSB0 buffer was filling up and when I came to read it I was reading GPS messages fromn the oldest part of the buffer, this made my readings up to 3 minutes old!! So I didn't recognise them as current speed. Now sorted by clearing buffer at beginning of loop and the n reading GPS data that is just entering. (Cannot do this with GPSD as a normal buffer clear does not clear GPSD data)

    cheers

    Peter

    ReplyDelete
  29. HI Ben,
    Great article. I am really new to this programming up Arduino and other items. I am developing a logging system and we have the waveshare 4.2 and 2.7 black and white e paper displays. I have downloaded the software. I have the teensey 3.2 and I am unsure how you load up the hex files as I keep getting errors. Is the a quick guide to making this work. Also does the hex file save to the screen and make it update like that when using a different controller.

    Thanks

    Stuart

    ReplyDelete
  30. Great video, article and explanation!!!
    excellent work.
    Does this work only with the 4.2 in display.
    Did anyone try it with 7.5"?
    I downloaded the epd7in5.cpp but it looks complete different

    ReplyDelete
  31. Hello Ben,

    I have technical problem on a partial update on epaper (display become grey and partial update like blurred even at the first update).
    I already discuss with JM Zingg who make the GxEPD2 library.
    We think it is a change in ink sand it would be very nice to get your support. You could contact me with e.fiancette at gmail.com
    I will send ou some pictures. Regards

    ReplyDelete
  32. Hello Ben Krasnow,

    I also have a problem with the partial update on epaper.
    Your proposed LUT tables for fast refresh work well with my tested Waveshare epaper 4.2", but no longer work with Good Display epaper 4.2" that I have just bought (partial update is very blurred). Maybe, the manufacturer has changed something in its latest version.
    I have tried the fast refresh LUT tables in Good Display sample code. The partial update is clearer and better but there are always the shadows of the previous images.
    So, I need to understand the meaning of the parameters in order to choose the desired configuration. Could you explain each parameter that you have selected for the first line of each LUT table.

    Thank you in advance.

    ReplyDelete
  33. Many thanks for this excellent video!!!

    ReplyDelete
  34. Hello Ben,
    Great video. I'm in the process of porting your driver to the Meadow board (C# .NET iOT device). Once I get it working would you or anyone else on here be interested in it? Ideally I'd like to get it included into the Meadow.Foundation library, possibly togglable, so that it ships with a future update and devs can have the choice of they want the quick updates or not.

    Keep up the great work!!

    ReplyDelete
  35. Excellent article and video indeed (as expected of Mr Ben) !
    (I jump on the occasion to express my solicitude regarding the recent burglary of your lab).

    This very video sprung my need for tinkering again !

    On the topic of EPDs, I'm on the verge of investigating the possible existence of undocumented opCodes for loading register LUTs, more precisely in the range [0x25..0x2F], since I wager there must be 9 LUTs in total, controlling RED/YELLOW repeatable (W2W,B2B,R2R) permutations (W2B, B2R...) on trichromic displays.

    So far, I've put my hand on two datasheets of two UC8151x revisions, namely UC8151C and UC8151D, both complementing each other (same opcodes and register flags, some opcodes missing or only present on one document only).

    If anyone has some idea on this very matter, please do ping me. ;-)

    Quick question: does anyone ever tested an OTP dump of these displays ( opCode 0xA2, "Read OTP") ? I cannot do so for now, since the 2.9" modules I own only offer a MOSI pin, no MISO.

    I'll be starting testing this theory on monday (hopefully not polarizing my test displays in the process while shooting in the dark, since my these modules do not have any MISO pin... hurgh. )

    ReplyDelete
  36. erratum : "Quick question: has anyone ever tested..."
    ( something about not proofreading when typing in another language... sorry )

    ReplyDelete
  37. PS : Somehow, I can't tell if the structure of those LUT are differente on BW and BWR/Y models and there's only 4 'color permutation' LUTs, or if there are some undocumented opcode, as I said... grrr.

    ReplyDelete
  38. Okay, so, as promised, here are the results of my research (WIP)

    First : forget about the UC8151D datasheet provided by Good-Display, as it's incomplete (the 861KB one I could only found on the web is anyway).
    One should use the GDEH029Z13 datasheet instead, as most of the opCode are described there.

    Good-Displays 2.9" tri-color EPD (the GDEH029Z13 I'm "murdering" in this case) uses the UC8151D, mind the rev. D , which has some peculiar LUTs :

    Each one of LUTC(vcom), LUTB, LUTW and LUTR are 60 bytes (6 bytes x10 phases),
    ¤ 10 groups usable in color mode (PSR[4]:KW/R bit off).
    ¤ 6 groups only used in B&W mode (PSR[4]:KW/R bit on).
    ¤ Every one of them takes a different name (offsets unchanged) depending on the color mode, for the sole purpose of understanting their roles. LUTR is LUTB2W, LUTW is LUTW2B and LUTB is LUTB2B.

    The LUTWW is a bit peculiar :
    ¤ 6 groups only
    % It is never used in color mode, only in B&W when KW/R=1 !

    Now more about the LUTOPT opcode : I mentioned LUTC is 60 bytes...as it doesn't offer the last 2 ST_XON/ST_CHV flags registers at its end, like on the UC8151c. Those two register are here set as parameters of the LUTOPT command, plus some cryptic "dummy" and "extra" group state flags, that could (imho) silence some groups in the LUTs for timing purposes.

    To be continued.

    ReplyDelete
  39. Thank you so much for sharing, i could use your custom LUT on a Waveshare 7in5 display [the controller is the ultra chip UC8179].

    The Waveshare provided demo code and library does not support LUT.
    I had to create some new functions to write LUT to the controller at the right address and enable the use of LUT instead of ROM.

    It works perfectly. It has some ghosting but i's normal since the screen does not flicker. I nedded to remove the ugly flicker between each frame refresh for a demo prototype.

    ReplyDelete
    Replies
    1. Hi greffeb... Sorry for the late reply (gmail "social networks" tab... something something).

      My LUTs or rather the way I tinker with them are/is available in an "issue" message of the U8glib's github.

      Here's a link to it : https://github.com/olikraus/u8g2/issues/1393#issuecomment-853008069

      Delete
  40. I've written my own eink library to my 4.2" waveshare display and it works great but using the slow luts from their sample code just wasn't cutting it for what I want to do but I added your quick luts to my code and they work perfectly. At any time I can call either lut initialization to either do a full refresh or a quick update. Makes GUIs much snappier, but allows nice clean updates when necessary. Thank you for sharing your example code and all you do for the science/research communities.

    ReplyDelete
  41. In the epdif.cpp you use (in function SPI) 'digitalWriteFast(CS_PIN, LOW);' and 'digitalWriteFast(CS_PIN, HIGH);'
    Didn't make that much difference with a standard digitalWrite.

    Other than that: thanks for the upgrade of the epd4in2 !

    ReplyDelete
  42. I'm trying to use this on a 1.54 inch RBW e ink but can't seem to get it to work. Anyone have any advice?

    ReplyDelete
  43. For those who come looking, here is an archive link for the e-paper theory.

    https://web.archive.org/web/20171118172235/http://www.multicomponent.se:80/sub_group_files/13dae3f428be3929dc13fed1f79c5e40.pdf

    ReplyDelete