Code Monkey home page Code Monkey logo

Comments (177)

mcer12 avatar mcer12 commented on August 19, 2024 5

There is a version of ED097TC2 with touchscreen and backlight, so just throwing it out there.
https://www.aliexpress.com/item/1005001268418194.html

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024 1

Received new pcbs and should also receive the ED060XC3 finally today, it was on the way for what, over two months? lol! So I will do some testing. I dont have very high expectations since I worked without datasheet but lets see :)

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024 1

Just managed to make it work! Both ED060XC3 and ED060XD4 work out of the box using ED097TC2 definition in menuconfig. ED060XC3 looks just as good as ED097TC2, same contrast, awesome. ED060XD4 has very bad contrast but that can be due to VCOM setting or slightly different timing. Neither of the displays came with VCOM specified so I used 1.62 from my ED097TC2 :)

Gotta admit, I was afraid it will release the magic smoke since I just guessed the pinout :D No smoke, dragon!

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

Found this digitizer, it's not quite the same size as 6" display but might be interesting since it should be fairly easy to implement.
https://www.aliexpress.com/item/32691474609.html

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

Another thing I found is that ED060XD4 (ED060XC3) should be using Cypress TMA445 touch IC (if you order version with touch).
http://www.cypress.com/files/cytma445-truetouch-multi-touch-all-points-touchscreen-controller-datasheetpdf
And linux driver, might come handy:
http://read.pudn.com/downloads648/sourcecode/embedded/2633827/kernel/drivers/input/touchscreen/cyttsp4_device_access.c__.htm

from epdiy.

vroland avatar vroland commented on August 19, 2024

For touch screen overlays there are bigger ones available as well: https://www.aliexpress.com/item/32892604142.html?spm=a2g0s.9042311.0.0.27424c4dw73ARr These have a Goodix controller chip and afaik there is already an Arduino driver out there.

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

Adding external PSRAM to WROOM module
https://www.reddit.com/r/esp32/comments/j7kxx2/psram_on_wroom/

from epdiy.

vroland avatar vroland commented on August 19, 2024

from epdiy.

vroland avatar vroland commented on August 19, 2024

There is a version of ED097TC2 with touchscreen and backlight, so just throwing it out there.
https://www.aliexpress.com/item/1005001268418194.html

That's a nice one. Btw, do you know any tricks for searching in AliExpress? When i search for ED097TC2 directly nothing turns up, but sometimes it is listed in the suggestions.

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

@vroland I don't... maybe it's your region. Does it let you order the one I linked?

from epdiy.

vroland avatar vroland commented on August 19, 2024

Yes, I could order it, but I cannot find it via search :D

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

ED0970D2 seems to be the same as ED097TC2/OC4 but also have digitizer. In this case it looks like the digitizer is analog. No backlight.

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

https://imgur.com/a/CPPmDYQ

I ramped up VCOM to -2.6V which is pretty high and its much better (it's the one without foil in the image), still lower contrast than ED060XC3 tho (fun fact: ED060XC3 is cheaper :) ). And sorry for spamming, I am very excited as I didn't really expect for it to work :) I will create separate issue to discuss these displays.

from epdiy.

vroland avatar vroland commented on August 19, 2024

Nice work! Just wondering: These displays have a 34-pin connector, right? Would you mind documenting the pinout, so I can make an adapter board from the 33pin connector?
And the VCOM value might be right, when I search for the XD4 I get this site: https://utradioguide.com/products/ed060xd4-c200-touch-screen-display-lcd-fur-pocketbook-626-plus-pocketbook-626-plus-pocketbook-626-p-nicht-zu-verwenden-um-pocketbook-626-2/ . One of the pictures shows a label with a -2.85V VCOM ;)

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

Yes, the connetor and pinout is the same as XC5, just with pin numbers reversed (!!!). I was searching for XC5 images to see what the usual vcom is and its usually between 2.5-2.9 which works great for my XD4. The contrast is now on par with XC3 and even looks little more crisp.

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

This assentially should add support for:
ED060XC3
ED060XD4
ED060XC5
ED060KD1
ED060KC1
ED060XD6
ED060XH2
ED060XC9
ED060XG1

I was also doing some digging on ED060SCF and similar types but that one is most probably same connector but unknown pinout (from visual inspection of the flex cable, compared to XC5 the traces don't match).

from epdiy.

vroland avatar vroland commented on August 19, 2024

Pins reversed? Wow :D The ED060XH7 looks promising as well, with a specified contrast of 16:1 (vs. 12:1) and touch + front light for ~50$.

ED060XC3
ED060XD4
ED060XC5
ED060KD1
ED060KC1
ED060XD6
ED060XH2
ED060XC9

Modulo pin permutation :D

from epdiy.

vroland avatar vroland commented on August 19, 2024

Have you had any luck getting touch to work, yet?

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

I am a cheap guy so I only have the cheap displays without touch :D

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

Jokes aside, I was curious about it but I barely know linux and porting touch drivers from it to the ESP is something I don't have time for nor do I expect to succeed :D

from epdiy.

vroland avatar vroland commented on August 19, 2024

Ah, ok. Fair enough ;) Currently I do not really have a project for a 6" panel either, so this will have to wait.
Usually, these are just I2C-connected and you have to read some registers to get events, but writing a nice driver for the ESP is of course a bit more time-consuming.

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

Turns out ED060SCF also works flawlessly with ED060XC5 pinout. I didn't think so at first because the traces looked pretty different but following key traces to the chip, turns out it's actually pin-compatible. That means:
ED060SCF
ED060SCN
ED060SCP

should all be compatible using my connector pinout :)
This covers all kindle paperwhite generations and most kindle 4/5/7s.

Adding ED060SC7 connector would add support for:
ED060SC7
ED060SCG
ED060SCE
ED060SCM
ED060SCT
This would make the board pretty much compatible with all widely available book reader displays

from epdiy.

vroland avatar vroland commented on August 19, 2024

So only the ED060XC3 has its pins reversed? But that would make it way easier to drive recycled screens :)
I guess it would make sense then to remove the 39-pin connector from the bottom and provide an adapter board instead, leaving the board with a 33pin and 34 pin connector? Or add it to the top at the cost of a bigger form factor...

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

Sorry I guess I said it unclearly, ED060XC3 has only pin numbers switched on the flex cable but otherwise it's exactly 1:1 like XC5. Another confusing thing is that XC3 (and the same displays) have the flex cable glued to the display, XC5 does not so it may look different when it's not. These images should be self-explanatory :)
XC3:
https://ae01.alicdn.com/kf/HTB1OaJKSFXXXXbTaXXXq6xXFXXX7.jpg?size=87752&height=1000&width=1000&hash=9c1cb17af28fbb6006537e52c23133a7
XC5:
https://rounded.com/images/detailed/123/sony-reader-prs-t3-e-ink-display-ed060xc5-lf_image-1.png

from epdiy.

vroland avatar vroland commented on August 19, 2024

Ah, ok, interesting. So there are two types of 34pin connector pinouts, the XC5-like (http://www.universaldisplay.asia/wp-content/uploads/2012/10/ED060XC5.pdf) and SC7-like (https://www.waveshare.net/w/upload/7/7c/6inch-e-paper-datasheet.pdf, http://www.universaldisplay.asia/wp-content/uploads/2012/10/ED060SC7-2.0.pdf). Or am I missing one?

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

Yes, it should be just these two. Only annoing thing si that the SC7 connector is not available on lcsc and costs like $2 a piece on mouser :/

from epdiy.

vroland avatar vroland commented on August 19, 2024

Don't they both have 34 pins with a 0.5mm pitch? This one https://lcsc.com/product-detail/FFC-FPC-Connectors_XKB-Connectivity-X05A20H34G_C528053.html is priced reasonably and looks like it will survive connecting / disconnecting a few times.

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

No, these have the 90degree connector
https://ae01.alicdn.com/kf/HTB1NUpKp.R1BeNjy0Fmq6z0wVXam/6-inch-ED060SC7-LF-C1-E-ink-LCD-For-AMAZON-KINDLE-3-D00901-k3-ebook-reader.jpg

from epdiy.

vroland avatar vroland commented on August 19, 2024

Oh, those weird mezzanine connectors :/ The AXT434124 (Edit: AXT334124) seems to be available on aliexpress though. It's still not the most convenient source, but at least cheaper...

from epdiy.

vroland avatar vroland commented on August 19, 2024

With some luck, something like this https://lcsc.com/product-detail/Mezzanine-Connectors-Board-to-Board_HRS-Hirose-DF40C-40DS-0-4V-51_C424644.html would work. I'll have to compare datasheets to be sure though.

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

probably won't fit because of larger inner circle

from epdiy.

vroland avatar vroland commented on August 19, 2024

Jep, they only sell even pin counts, like 30,40,50, but not 34 :/

from epdiy.

2dom avatar 2dom commented on August 19, 2024

I just got the board to work. I am rather happy with it - thanks for the great work. One Question though - the contrast and black levels of the display are not very good. Is this limited by the hardware or can this also be influenced / improved by driving patterns etc?

from epdiy.

vroland avatar vroland commented on August 19, 2024

Did you calibrate the VCOM voltage to your display's value?
Other than that, especially for older displays, the contrast may not be great. Most older ones have their Contrast ratio specified as 10:1 or 12:1, the newer ones (ED097TC2, etc) as 16:1. Since they're reflective this is not really comparable with LCDs, but afaik as long as your VCOM is correct you can't really do much more.
There seems to be some sort of "overdrive" effect if you push e.g. the white pixels very hard, but this returns to the "normal" white levels pretty quickly, even with disconnected power. So this is probably limited by particle diffusion and overdriving the display in this way will probably shorten its lifespan.

from epdiy.

2dom avatar 2dom commented on August 19, 2024

Yeah - I tweaked VCOM for best results. I have the ED097OC4 - is this considered an "old" display?

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

@2dom yes, did you try to switch to ED097OC4 in menuconfig?
https://epdiy.readthedocs.io/en/latest/getting_started.html#selecting-a-display-type

from epdiy.

2dom avatar 2dom commented on August 19, 2024

Yes .. also the _OLD variety

from epdiy.

2dom avatar 2dom commented on August 19, 2024

Just bought an ED060XC3 (saw your conversion from other issue)... still not sure how to wire this one up though...

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

You will have to either design your own board or wait for the new revision which will include different connector for this display.

from epdiy.

2dom avatar 2dom commented on August 19, 2024

I think I will wait for now :) A few cool additions to the board would be:

  • LiPo connector & charger
  • Accelerometer for detecting orientation
  • free up more gpios for other stuff

Just a thought :)

from epdiy.

vroland avatar vroland commented on August 19, 2024

@2dom Yes, the OC4 is one of the displays with 12:1 contrast, so when you look for pictures of the Kindle DXG that should more or less match that.

  • LiPo connector & charger
  • Accelerometer for detecting orientation
  • free up more gpios for other stuff

Yes, more GPIOs would definitely be nice, I'll see what i can do without compromising performance.
I'm not sure how much of a benefit a lipo charger and accelerometer would be, since you can get modules for that for ~1$ and it would make the board larger and more complex if you don't need it. Also, I'm not sure I have the expertise to design lipo charging circuitry correctly...

from epdiy.

2dom avatar 2dom commented on August 19, 2024

Another finding - running those displays with some gamma corrections really made a difference for me (currently using 1.3). This pushes the lows a little bit and brings out the details

from epdiy.

vroland avatar vroland commented on August 19, 2024

That is mostly for images, right? But yes, I should add that to the documentation.

from epdiy.

vroland avatar vroland commented on August 19, 2024

Another (more or less) crazy idea: We could use some SRAM as lookup tables that are programmed for every frame, eliminating the need to do that on the CPU side. This would effectively allow to stream the raw pixel data to the SRAM address bus which outputs to the display bus.
This way, we could either save four pins (as we only need a 4-bit wide I2S) or get really fancy:
Some of the displays @mcer12 mentioned seem to have flash chips with their waveform data on them. With the waveforms we could then generate a 256 byte look up table for each frames which handles each (old color, new color) combination. With an 8bit wide I2S, we could output 4 bits of the old image and 4 bits of the new image as lookup table address to the SRAM.
That would allow for any grayscale-to-grayscale transitions (provided we can use the vendor waveforms), at pretty good speeds. Or improve refresh speeds with the curent approach. Only synchronizing the horizontal clock signal and data correctly would require some thought.
Hope that sounds somewhat reasonable :D

from epdiy.

2dom avatar 2dom commented on August 19, 2024

Sounds like a solid plan - I like it πŸ˜ƒ. Do you have a data sheet for such displays ?

from epdiy.

2dom avatar 2dom commented on August 19, 2024

I'm getting there with the image side of things ... Looking good. The key is dithering - maybe we can push this to the DMA part as well :)

from epdiy.

2dom avatar 2dom commented on August 19, 2024

IMG_20201208_195439

from epdiy.

2dom avatar 2dom commented on August 19, 2024

Has less contrast in real life though

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

@2dom I am developing my own boards compatible with epdiy with battery charging, 4 buttons and 28uA deep sleep current. One for ED060XC3 and one for the ED097OC4/TC2. I shared an early version (ED060XC3 attached) here few days ago: https://www.reddit.com/r/esp32/comments/k4uxvh/6_kindle_paperwhite_display_with_esp32/
I intend for it to be fully compatible with V5 epdiy pcb so we first need to establish final pin scheme for the V5 before I can finalize the pcb.

from epdiy.

2dom avatar 2dom commented on August 19, 2024

Hey @mcer12 - this looks great. Exactly what I was looking for. :)

Will you be sharing the gerbers when you are done too?

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

Sure, wouldn't mention it otherwise ;)

from epdiy.

2dom avatar 2dom commented on August 19, 2024

Great! - I was just going to make one or two boards as a Christmas present (epaper photo frame) but this is way too much fun to stop here!

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

@2dom Especially once you realize these 6" displays are same price as 1.54" waveshare displays. I am very tempted to buy bunch of them :D

from epdiy.

vroland avatar vroland commented on August 19, 2024

@2dom I'm actually up to something similar :D And the dithering is a good idea. I guess you did the dithering on a desktop computer and not on the ESP32? For my picture frame version, I want to read JPEGs off a sd card requiring as little pre-processing as possible.

from epdiy.

vroland avatar vroland commented on August 19, 2024

Regarding the flash chip: The SC7 (http://www.universaldisplay.asia/wp-content/uploads/2012/10/ED060SC7-2.0.pdf) has it described in its data sheet.

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

@vroland the 6" displays with 34pin connector all have the chip on the flex cable. Some have winbond branded chip, some have other (can't remember the brand now) but the chips look the same so I would assume they behave the same.

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

@vroland you can do the dithering simply by adding a parameter in your python script when compressing the image. ;)

from epdiy.

vroland avatar vroland commented on August 19, 2024

Yes, but I for the picture frame I don't want people to have to run the script ;)

from epdiy.

2dom avatar 2dom commented on August 19, 2024

I implemented it on the esp

from epdiy.

2dom avatar 2dom commented on August 19, 2024

Floyd Steinberg is rather trivial to do

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

@2dom please share your code

from epdiy.

2dom avatar 2dom commented on August 19, 2024

Sure ... but it is pretty much hacked together at this point - lot's of room for improvements and optimizations :)

  • This will read jpeg files from the SD card or SPIFFS file system
  • Decode them one by one, scale them to (display) size and write them to a gray-scale frame buffer
  • Apply Floyd Steinberg dithering and gamma correction
  • Write to display
  • It currently assumes landscape orientation of the display and scales / centers portrait pictures according
  • Quirks: jpegs have to be encoded without using "Progressive" encoding and cannot be too big (otherwise the jpeg decoder will quit)
  • Don't use GPIO12 (HSPI MISO) for SD card or the ESP will neither boot nor upload code

Libraries:

#include "Arduino.h"
#include "esp_heap_caps.h"
#include "esp_log.h"
#include "esp_timer.h"
#include "esp_types.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "sdkconfig.h"
#include <stdio.h>
#include <string.h>

#define IS_SD



#ifdef IS_SD
  #include "SD.h"
  #include "FS.h"
  #include "SPI.h"
#else
  #include "SPIFFS.h"
  
#endif

#include "epd_driver.h"
#include <JPEGDecoder.h>


#ifdef IS_SD
  SPIClass spiSD(HSPI);
#endif

uint8_t *img_buf;
uint8_t *source_buf;

uint16_t ep_width=1200;
uint16_t ep_height=825;

uint16_t this_pic=0;

double gamma_value = 1.2;
uint8_t gamme_curve[256];

/*====================================================================================
  This sketch contains support functions to render the Jpeg images.

  Created by Bodmer 15th Jan 2017
  ==================================================================================*/

// Return the minimum of two values a and b
#define minimum(a,b)     (((a) < (b)) ? (a) : (b))



uint8_t find_closest_palette_color(uint8_t oldpixel)
{
  return (round((oldpixel / 16)*16));
}

//====================================================================================
//   Decode and paint onto the TFT screen
//====================================================================================
void jpegRender(int xpos, int ypos) {


  // retrieve infomration about the image
  uint16_t  *pImg;
  uint16_t mcu_w = JpegDec.MCUWidth;
  uint16_t mcu_h = JpegDec.MCUHeight;
  uint32_t max_x = JpegDec.width;
  uint32_t max_y = JpegDec.height;

 

  // Jpeg images are draw as a set of image block (tiles) called Minimum Coding Units (MCUs)
  // Typically these MCUs are 16x16 pixel blocks
  // Determine the width and height of the right and bottom edge image blocks
  uint32_t min_w = minimum(mcu_w, max_x % mcu_w);
  uint32_t min_h = minimum(mcu_h, max_y % mcu_h);

  // save the current image block size
  uint32_t win_w = mcu_w;
  uint32_t win_h = mcu_h;


  uint8_t mcu_h_scaled=mcu_h * ep_height / max_y;

  // record the current time so we can measure how long it takes to draw an image
  uint32_t drawTime = millis();

  // save the coordinate of the right and bottom edges to assist image cropping
  // to the screen size
  max_x += xpos;
  max_y += ypos;

  // read each MCU block until there are no more
  while ( JpegDec.read()) {

    
    // save a pointer to the image block
    pImg = JpegDec.pImage;

    // calculate where the image block should be drawn on the screen
    int mcu_x = JpegDec.MCUx * mcu_w + xpos;
    int mcu_y = JpegDec.MCUy * mcu_h + ypos;
  

    // check if the image block size needs to be changed for the right edge
    if (mcu_x + mcu_w <= max_x) win_w = mcu_w;
    else win_w = min_w;

    // check if the image block size needs to be changed for the bottom edge
    if (mcu_y + mcu_h <= max_y) win_h = mcu_h;
    else win_h = min_h;

    // copy pixels into a contiguous block
    if (win_w != mcu_w)
    {
      for (int h = 1; h < win_h-1; h++)
      {
        memcpy(pImg + h * win_w, pImg + (h + 1) * mcu_w, win_w << 1);
      }
    }
      
    unsigned long pixel=0;
    for (uint16_t by=0; by<win_h;by++)
    {       
      for (uint16_t bx=0; bx<win_w;bx++)
      {
        uint16_t this_pixel=pImg[pixel];
        uint8_t red = ((((this_pixel) & 0xf800) >> 11) << 3);
        uint8_t green = ((((this_pixel) & 0x07e0) >> 5) << 2);
        uint8_t blue = (((this_pixel) & 0x001f) << 3);
        uint8_t gray=(red+green+blue)/3;
        //line_buf[(by+mcu_y)*max_x+bx+mcu_y]=gray;
        uint16_t nearestMatch_y =  (int)((by+mcu_y) * ep_height / max_y);
        uint16_t nearestMatch_x=0;
        if (max_x>max_y)
           nearestMatch_x =  (int)((bx+mcu_x) * ep_width / max_x);
        else
           nearestMatch_x =  (int)((bx+mcu_x) * ep_height / max_y);
       
        source_buf[nearestMatch_x+nearestMatch_y*ep_width]=gamme_curve[gray];
        //epd_draw_pixel(nearestMatch_x,nearestMatch_y,gray,img_buf);
        pixel++;
      }
    }
  }


unsigned long pixel=0;
// Dithering
 for (uint16_t by=0; by<ep_height;by++)
  {       
    for (uint16_t bx=0; bx<ep_width;bx++)
    {
        int oldpixel = source_buf[pixel];
        int newpixel = find_closest_palette_color(oldpixel);
        int quant_error = oldpixel - newpixel;
        source_buf[pixel]=newpixel;
        if (bx<(ep_width-1))
          source_buf[pixel+1] = min(255,source_buf[pixel+1] + quant_error * 7 / 16);
                  
        if (by<(ep_height-1))
        {
          if (bx>0)
            source_buf[pixel+ep_width-1] =  min(255,source_buf[pixel+ep_width-1] + quant_error * 3 / 16);
          
          source_buf[pixel+ep_width] =  min(255,source_buf[pixel+ep_width] + quant_error * 5 / 16);
          if (bx<(ep_width-1))
            source_buf[pixel+ep_width+1] = min(255,source_buf[pixel+ep_width+1] + quant_error * 1 / 16);
        }
        pixel++;
    }
  } 

  // Write to displayv
  pixel=0;

  //epd_draw_grayscale_image(epd_full_screen(), 0);
  uint16_t scaled_width = (int)(max_x * ep_height / max_y); 
  uint16_t padding=0;
  uint16_t right_end = ep_width;

  if (max_x<max_y)
  {
    padding= (ep_width-scaled_width)/2;
    right_end = scaled_width+padding;
  }
  
  for (uint16_t by=0; by<ep_height;by++)
  {       
    for (uint16_t bx=0; bx<ep_width;bx++)
    {
          //epd_draw_pixel(bx+padding,by,0,img_buf);
         
          
          if (bx<=right_end)
            epd_draw_pixel(bx+padding,by,source_buf[pixel],img_buf);
          
          if (bx<padding)
            epd_draw_pixel(bx,by,128,img_buf);

          if (bx>right_end)
            epd_draw_pixel(bx,by,128,img_buf);
              
          // else
     
      
      pixel++;
    }
  }  
  // calculate how long it took to draw the image
  drawTime = millis() - drawTime;

  // print the results to the serial port
  Serial.print  ("Total render time was    : "); 
  Serial.print(drawTime); Serial.println(" ms");
  Serial.println("=====================================");

}

//====================================================================================
//   This function opens the Filing System Jpeg image file and primes the decoder
//====================================================================================
void drawFSJpeg(const char *filename, int xpos, int ypos) {

  Serial.println("=====================================");
  Serial.print("Drawing file: "); Serial.println(filename);
  Serial.println("=====================================");

  // Open the file (the Jpeg decoder library will close it)
#ifdef IS_SD
  File jpgFile = SD.open(filename);    // File handle reference for SPIFFS
#else
  fs::File jpgFile = SPIFFS.open( filename, "r");    // File handle reference for SPIFFS
#endif
  
  //  File jpgFile = SD.open( filename, FILE_READ);  // or, file handle reference for SD library
 
  if ( !jpgFile ) {
    Serial.print("ERROR: File \""); Serial.print(filename); Serial.println ("\" not found!");
    return;
  }

  // To initialise the decoder and provide the file, we can use one of the three following methods:
  //boolean decoded = JpegDec.decodeFsFile(jpgFile); // We can pass the SPIFFS file handle to the decoder,
  //boolean decoded = JpegDec.decodeSdFile(jpgFile); // or we can pass the SD file handle to the decoder,
  #ifdef IS_SD
      boolean decoded = JpegDec.decodeSdFile(filename); // or we can pass the SD file handle to the decoder,

  #else
      boolean decoded = JpegDec.decodeFsFile(filename);  // or we can pass the filename (leading / distinguishes SPIFFS files)

  #endif                                        // The filename can be a String or character array
  if (decoded) {
   

    // render the image onto the screen at given coordinates
    jpegRender(xpos, ypos);
  }
  else {
    Serial.println("Jpeg file format not supported!");
  }
  jpgFile.close();
}

uint8_t file_count=0;

String file_names [256];
void list_files()
{
   
   static File file;
      Serial.println("list");
      File root = SD.open("/");
      file = root.openNextFile();
      while (file) {
        if (file.isDirectory()) {
          Serial.print("DIR: ");
          Serial.println(file.name());
      
        }
        else {
          Serial.print("FILE: ");
          Serial.print(file.name());
          Serial.print("  SIZE: ");
          Serial.println(file.size());
          file_names[file_count]=file.name();
          file_count++;
       

    
        }
        file = root.openNextFile();
      }
      Serial.println();
}

void setup() {

  Serial.begin(115200);
  epd_init();

#ifdef IS_SD
  Serial.print("Initializing SD card...");

  
  spiSD.begin(14, 34, 13, 15);
  if (!SD.begin(15,spiSD )) {
    Serial.println("initialization failed!");
    return;
  }
    uint8_t cardType = SD.cardType();

    if(cardType == CARD_NONE){
        Serial.println("No SD card attached");
        return;
    }

    Serial.print("SD Card Type: ");
    if(cardType == CARD_MMC){
        Serial.println("MMC");
    } else if(cardType == CARD_SD){
        Serial.println("SDSC");
    } else if(cardType == CARD_SDHC){
        Serial.println("SDHC");
    } else {
        Serial.println("UNKNOWN");
    }

    list_files();
    this_pic=random(file_count-1);
    Serial.println("Numer of files: " + String(file_count));
  
#else
  Serial.print("Initializing SSPIFFS card...");
  if (!SPIFFS.begin(true)) {
    Serial.println("initialization failed!");
    return;
  }
#endif
  Serial.println("initialization done.");
  
  
  // put your setup code here, to run once:
  img_buf = (uint8_t *)heap_caps_malloc(EPD_WIDTH * EPD_HEIGHT / 2, MALLOC_CAP_SPIRAM);
  source_buf = (uint8_t *)heap_caps_malloc(EPD_WIDTH * EPD_HEIGHT, MALLOC_CAP_SPIRAM);
  
  Serial.println("heap allocated");
  //memcpy(img_buf, dragon_data, EPD_WIDTH * EPD_HEIGHT / 2);
  Serial.println("img copied");

  
  double gammaCorrection = 1.0 / gamma_value;
  for (int gray_value =0; gray_value<256;gray_value++)
    gamme_curve[gray_value]= round (255*pow(gray_value/255.0, gammaCorrection));
  
  drawFSJpeg("/tiffany.jpg", 0, 0);
  Serial.println("EP Power On");
  epd_poweron();
  Serial.println("EP Power clear");
  // epd_draw_image(epd_full_screen(), img_buf, WHITE_ON_WHITE);
  epd_clear();

  epd_push_pixels(epd_full_screen(), 20, 0);
  epd_push_pixels(epd_full_screen(), 20, 0);
  epd_push_pixels(epd_full_screen(), 20, 0);
  epd_draw_image(epd_full_screen(), img_buf, WHITE_ON_BLACK);

  
  Serial.println("EP Power Off");

  epd_poweroff();

}

void loop() {
  
  const char * this_filename = file_names[this_pic].c_str();
  drawFSJpeg(this_filename, 0, 0);
  Serial.println("EP Power On");
  epd_poweron();
  Serial.println("EP Power clear");
  // epd_draw_image(epd_full_screen(), img_buf, WHITE_ON_WHITE);
  epd_clear();
 
  Serial.println("EP Write image");
 
  epd_push_pixels(epd_full_screen(), 20, 0);
  epd_push_pixels(epd_full_screen(), 20, 0);
  epd_push_pixels(epd_full_screen(), 20, 0);
  epd_draw_image(epd_full_screen(), img_buf, WHITE_ON_BLACK);

  Serial.println("EP Power Off");

  epd_poweroff();
  this_pic++;
  if (this_pic==file_count)
    this_pic=0;
  delay(10000);


}

from epdiy.

2dom avatar 2dom commented on August 19, 2024

Another thought reg. improvements - work with a 8bit gray scale frame buffer in the driver and do the reduction to 4 bit per pixel on the fly / in the DMA. This would make it much simpler and faster to interact with the frame buffer

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

For low power, GPIO12 shouldn't be used at all or HIGH by default as it has built-in external pullup on ESP32-wrover

from epdiy.

vroland avatar vroland commented on August 19, 2024

@2dom Nice, I'm curious to try that :)
Regarding the external LUT: I just realized that I forgot that the EPD input is always 4 pixels in parallel, so to use an external LUT we would need a 16bit wide bus (or 32bit and 4GB! LUT for old / new), so that wouldn't be worth it. And using some kind of buffer like a shift register would make things slow again. So I guess I'll focus on low power then.

Also, I used 8bit buffers in the beginning and I think it would be a performance hit. This is because most large buffers live in the external PSRAM, so modifying pixels would rather be bandwidth-limited instead of compute-limited. To make using the 4bit buffers easier, I exposed some library functions.
Futhermore, for drawing a buffer to the screen it has to be read 15 times from the PSRAM, and reading 7.5MB or 15MB in total definitely makes a difference there.

from epdiy.

vroland avatar vroland commented on August 19, 2024

@2dom Would you mind making adding the picture frame code as an example? Just add a license and PR it? :) I think this "digital picture frame" is something quite a few people would be interested in.

from epdiy.

2dom avatar 2dom commented on August 19, 2024

Sure ... will do. Unfortunately I just killed by display (Ripped the flex cable). 2020 just keeps on giving ....

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

@2dom To the contrary. 2020 gives opportunities! This is a great opportunity for you to buy a flex cable and teach yourself some microsoldering :P

from epdiy.

2dom avatar 2dom commented on August 19, 2024

Oh I have tried :) But then I noticed another crack where all that serious wiring is going on....

from epdiy.

2dom avatar 2dom commented on August 19, 2024

@vroland Just noticed ... I used the Arduino framework and threw out a few things to make it work. Not sure of how much help the example would be like that?

from epdiy.

vroland avatar vroland commented on August 19, 2024

Oh, this is unfortunate. I always tape them down first, that has helped me so far.

Well, we could just add a readme that links to the install instructions for the arduino IDF component. So it may not be for the beginner, but I think it may help some people.
I think I will also use another JPEG decoder (the one I used for the album covers in the MPD example, and is also included with the IDF), since that allows to set a pre-scaling factor which the library you linked does not expose.

from epdiy.

2dom avatar 2dom commented on August 19, 2024

@mcer12 How is that new board of yours coming along ? ☺️ Just received my 6inch display...

from epdiy.

vroland avatar vroland commented on August 19, 2024

@mcer12 @2dom I now have a (conecptually) final schematic in the v5 branch. The new board includes connectors for the ED060SC7 and ED060XC5 displays, auto-reset functionality and a LiPo charging circuit.
As I am not that familiar with battery circuitry, could you have a look if there are any issues with it (esp. @mcer12 )?

Here is the schematic as PDF:
epaper-breakout.pdf

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

@vroland looks fine, some suggestions:

  1. a a note to TP4056 for R9 to select value depending on the battery capacity. For something like 500mAh something around 6k should be used for example.
  2. I suggest CH340C instead of G, it's the same thing (1:1 pin compatible) except it doesn't require crystal+10pf caps. And costs the same.
  3. For low power CH340 needs it's own regulator and only be powered when USB is attached (using a schottky diode). I use XC6206 for these things because cheap :)
  4. I use B5819WS on high voltage boosters, works well for me and is tiny package. Would use the large diodes only on low voltage because of high current.

Also, is the pinout of ESP32 and 74HC4094 to be considered final?

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

@2dom need final pinout first to be compatible ;)

from epdiy.

vroland avatar vroland commented on August 19, 2024

@mcer12 Thanks for the feedback! I think the pinout should be mostly final, however, if I encounter something that's really in the way when routing, I might consider changing it. But I already started routing for the most important things, so it should most likely stay like this.
What else are you adding to your board, btw? ;)

from epdiy.

2dom avatar 2dom commented on August 19, 2024

Schematics looks good - maybe name the 5V rail something different as it will be less if running on battery. Another thought towards simplification would be to remove the under/over voltage protection as most lipo packs these days have that build in? Or leave it in and open the door for non-protected cells (16850 etc)?

from epdiy.

vroland avatar vroland commented on August 19, 2024

@2dom I thing I have some old cells without protection where it would be useful. But maybe a jumper to bypass protection if you don't need it so you don't need to populate it? On the other hand, this adds even more complexity.

from epdiy.

2dom avatar 2dom commented on August 19, 2024

Yeah ... you are probably right.

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

@vroland Personally, I would leave it to the user to optioanlly use external protection circuitry and remove it in the design (just add a note that external protection is required). Protection boards are widely available for 18650 batteries... but that's just my opinion.

from epdiy.

2dom avatar 2dom commented on August 19, 2024

Another thought would be to optimize the dump components to be included in the jlcpcb basic parts library for easy reproduction

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

@2dom most components have alternatives in jlcpcb parts library but you will have to source some of them either way. My board will probably be slightly better in terms of jlcpcb essembly service but you will still have to solder some number of components yourself.

from epdiy.

2dom avatar 2dom commented on August 19, 2024

@mcer12 Yeah - but I remember that I had to hand-solder some caps and resistors because they had some non-common value (was too cheap to pay the extra handling fee). Might make sense to check if all those need to be that specific value or something more standard / included in the basic parts library will do too.... (Same with mosfets etc, regulators, etc.)

from epdiy.

vroland avatar vroland commented on August 19, 2024

Ok, I'll remove the protection circuitry then. This is the part of the circuit I am the most unfamiliar with anyway ;)
With the V4 board all resistors and caps where JLCPCB basic parts in my order, yes, some components could be changed, like the coils. The diodes are extended parts as well, but the B5819W could be listed as alternative in the BOM. Maybe there are pin-compatible voltage regulators as well.

from epdiy.

vroland avatar vroland commented on August 19, 2024
1. a a note to TP4056 for R9 to select value depending on the battery capacity.  For something like 500mAh something around 6k should be used for example.

Hm, according to this data sheet https://dlnmh9ip6v2uc.cloudfront.net/datasheets/Prototyping/TP4056.pdf 2k is 580mA. Where do you get the 6k from?

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

I said "something like" 6k, that would give you around 220mA ;) The table is just examples for measure, you don't have to use the exact values. I like to charge the batteries slow (below 1C, 0.5C preferrably) for higher lifetime. 2k is perfectly fine for 18650 but way too high for say 250mAh lipo and OK for 500mAh I guess but not my choice.

from epdiy.

vroland avatar vroland commented on August 19, 2024

Ah, right, that makes sense :) I didn't have any low-capacity cells lying around, so I didn't think of that. I'll go with 6.8k then.

from epdiy.

vroland avatar vroland commented on August 19, 2024

@mcer12 @2dom
epaper-breakout.pdf
Iv'e removed the battery protection, changed the charge current resistor and added a regulator for the CH340C. Is there anything else I've missed?

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

@vroland Looks good to me. If you want less different components, you can use MCP1700 also for the CH340 it's pin compatible.

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

@vroland Oh one more thing since I mention the regulators. If you have an oscilloscope, I would check if the voltage on the main 3.3V doesn't dip when using wifi. MCP1700 is quite at the edge for ESP32 and I use large 470uF capacitor in my projects to compensate for the wifi current spikes.

from epdiy.

vroland avatar vroland commented on August 19, 2024

Unfortunately I don't have an oscilloscope, it would definitely be useful sometimes. So far I did not encounter any problems when using wifi, but that doesn't have to mean anything. With a quick search I couldn't find any parts with a similarly low current consumption but more current output, so a bigger cap sounds like a workaround for now.
Thanks for checking :)

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

@vroland I use ME6210 which should work well but I drop the large tantalum in anyway, it doesn't hurt anything... this one: C122309

from epdiy.

2dom avatar 2dom commented on August 19, 2024

Shouldn't the TP4056 be hooked up to VBUS instead of VIN ?

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

@2dom yes, also another diode should be used to separate CH340. I have it like this in all my battery projects:
https://www.dropbox.com/s/tl8f4w1v52uxxoc/Schematic_9.7inch%20e-ink%20controller_2021-01-02.pdf?dl=0

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

I think it was bleeding some current from BAT to VCC and to the CH340, hence the second diode.

from epdiy.

vroland avatar vroland commented on August 19, 2024

@2dom Good catch, thank you!
@mcer12 The current is bleeding through the TP4056? It's data sheet says it could be up to 6uA. With two diodes you get quite a voltage drop from the 5V in... But I guess efficiency is more or less irrelevant when running from USB.

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

Yes, the TP4056 by itself has 6uA draw but CH340 draws quite a bit through it. As I remember it anyway, it's been a while since I designed this... you can replace the diode with 0ohm resistor and see what difference it makes.

If anything, the voltage drop should make work easier for the 3.3V regulator :)

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

The issue is that if even tiny voltage appears on VCC of the TP4056, CH340 will suck it up.

from epdiy.

vroland avatar vroland commented on August 19, 2024

Ok, I've added the diode directly after the power supply for the tp4056, which would make it parallel to the power switcher (with the mosfet and other diode). Any issues with that?

from epdiy.

mcer12 avatar mcer12 commented on August 19, 2024

You probably mean CH340? It should be in series with the second diode, as seen in my schematic ;)

from epdiy.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.