mendhak / waveshare-epaper-display

At-a-glance dashboard for Raspberry Pi with a Waveshare ePaper 7.5 Inch HAT. Date/Time, Weather, Alerts, Google/Outlook Calendar
https://code.mendhak.com/raspberrypi-epaper-dashboard/
438 stars 65 forks source link

No red when using B e-paper #70

Open KaeroDot opened 8 months ago

KaeroDot commented 8 months ago

I have bought waveshare e-paper 7.5 inch V2 B. I have set the env.sh properly, I can see the generated png image contains some text in red (as shown in readme template 4), yet the e-paper display does not show any red text. The supposedly red text is shown in gray (very funny because this display is not grayscale!).

Hardware is connected properly - when I run waveshare example epd_7in5b_V2_test.py, I can see various images perfectly with some parts in red and some in black.

Looking at the waveshare code, I can see e.g. following:

    Himage = Image.open(os.path.join(picdir, '7in5_V2_r.bmp'))
    Himage_Other = Image.open(os.path.join(picdir, '7in5_V2_b.bmp'))
    epd.display(epd.getbuffer(Himage),epd.getbuffer(Himage_Other))

So the first input of function epd.display is black and white bmp image, and the black is displayed as red on the display. The second input is black and white bmp image, and the black is shown as black on the display.

Looking into the code displaying the calendar, display.py, the relevant part is at line 42:

    if waveshare_epd75_version == "2B":
        Limage_Other = Image.new('1', (epd.height, epd.width), 255)  # 255: clear the frame
        epd.display(epd.getbuffer(Himage), epd.getbuffer(Limage_Other))

I do not get this code. It seems to me the variable Limage_other contains only white image, so it cannot be used as red layer.

I have found that PIL library got function image.split, that splits the image by channels. So in this way I can remove a color channel. The split generates three images by channels, but every channel image contains also pixels that were originally black. So I do not know how to remove black parts of the image. Because the cairosvg use anti-aliasing, the generated image contains not only purely black, white and red pixels, but also many gray and light red pixels. Thus simple pixel arithmetic does not help (e.g. if pixel == (255,0,0)).

I could circumvent the issue by changing svg file, and set every part originally in black to e.g. green, keep red parts as red, and than split the image by channels, and display it:

    if waveshare_epd75_version == "2B":
        (red, green, blue) = Himage.split()
        epd.display(epd.getbuffer(red), epd.getbuffer(green))

This works and shows proper black and red texts on the display. However this is very strange method and there have to be something more intelligent. And also I have to change all icons to green so it is very stupid method. Yet I am not used to image processing so I do not know better way.

mendhak commented 8 months ago

All of this sounds very strange, definitely agree. You're not the first person to use the 7.5 V2 B with this project, surely someone would have posted if the colors were a problem.

I see other threads mentioning the 'red' waveshare screen, for example look at this one. https://github.com/mendhak/waveshare-epaper-display/issues/65

I see one comment mentioning which way the cable should be, maybe have a look at that one?

KaeroDot commented 8 months ago

I agree it sounds strange, however Ithe example (demo) in waveshare library works in my setup, showing black&red images, so cables and whole hardware of my setup are correct. And the waveshare code clearly shows one have to put in two B&W images, one for black layer, another for red layer. In your code, the Limage_Other variable contains an empty white image, so how could this work? Maybe previous versions of the waveshare library worked differently? I do not know.

mendhak commented 8 months ago

I've not got one of those screens so I simply copied the code from this comment here. It seemed to work for them at that time but if you can see a simplified way of redoing it happy to change the code. But as far as I can tell it shouldn't have to require complex operations like splitting, if the sample code is simple. I'd assume that the code to do it should match Waveshare's own sample code, that's how I've done the other screens.

KaeroDot commented 8 months ago

Strange it worked for @Karllebolla. I got the display working perfectly in nice black & red, but only using the stupid method with splitting by color channels. The whole svg contains only green or red text. The new code in display.py is:

if waveshare_epd75_version == "2B":
        (red, green, blue) = Himage.split()
        epd.display(epd.getbuffer(red), epd.getbuffer(green))

See .py and .svg in this commit: https://github.com/mendhak/waveshare-epaper-display/commit/b552b569fe18116121a4951233d49640f6b9ce33

Anyway the method is really stupid, some much better way must exist. So I do not recommend to include the code, just to remember it for reference if someone else get the same issue.

KaeroDot commented 7 months ago

The B display (red&black&white) refresh time is ~20 seconds. The crontab refreshing every 1 minute is not useful. For my setup, I have removed the clock from the display, so I need to refresh only every 15 minutes, but other users could be mislead? Maybe it would be good to mention this in the README.md?

B specifications: https://www.waveshare.com/product/displays/e-paper/epaper-1/7.5inch-e-paper-b.htm

jmason commented 7 months ago

hey folks, I have a red/black/white display too. Here's the shell script hackery I used to handle a full-colour image:

log "Separate black/red channels"
convert screen-output.png -channel R -separate only_black.png
pngtopnm screen-output.png > screen-output.pnm
pngtopnm only_black.png > only_black.pnm
ppmtopgm only_black.pnm | pnmsmooth | pgmtopbm -threshold -value 0.9999 | pbmmask > mask.pbm
pnminvert mask.pbm > mask_invert.pbm
pnmcomp -alpha=mask_invert.pbm mask_invert.pbm screen-output.pnm only_red.pnm
pnmtopng only_red.pnm > only_red.png

# Convert to a black and white, 1 bit bitmap
convert -colors 2 +dither -type Bilevel -monochrome only_red.png only_red.bmp
convert -colors 2 +dither -type Bilevel -monochrome only_black.png only_black.bmp

log "Display on epaper"
python3 display.py only_black.bmp only_red.bmp

And display.py contains:

    logging.debug("Read image files")
    black_image = Image.open(sys.argv[1])
    red_image = Image.open(sys.argv[2])

    logging.info("Display image file on screen")
    epd.display(epd.getbuffer(black_image), epd.getbuffer(red_image))
jmason commented 7 months ago

Also, yes, due to the slow screen refresh time, I've adapted my display to update hourly (and obvs not display minutes or seconds on the clock).