Waveshare e-paper display how to rotate?

All ESP32 boards running MicroPython.
Target audience: MicroPython users with an ESP32 board.
JumpZero
Posts: 54
Joined: Mon Oct 30, 2017 5:54 am
Location: Arcachon - France

Re: Waveshare e-paper display how to rotate?

Post by JumpZero » Fri Apr 26, 2019 2:08 pm

Hello,

@pythoncoder:
I’d like to have bigger fonts so I’ve check your micropython-font-to-py repo as you suggested here above.
But so far I had no success.
I understand as per your documentation that when using the writer as in:

Code: Select all

wri = Writer(device, font)
the device must inherit from framebuf
But in my code I don’t have such a device. I have tried to pass the framebuffer as a device

Code: Select all

wri = Writer(fb_portrait_black, freesans20)
but receive this error:

Code: Select all

AttributeError: 'FrameBuffer' object has no attribute 'width'
Seems normal: yes the FrameBuffer' object has no attribute 'width'

I tried to pass the EPD object:

Code: Select all

wri = Writer(e, freesans20)
But got this error:

Code: Select all

ValueError: Device must be derived from FrameBuffer.
So I’m a bit lost do I have to create an object from EPD and FrameBuffer? How can I do this?

Thanks in advance if you can help.

PS: my code is the same as posted here above + from writer import Writer + import freesans20, of course

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Waveshare e-paper display how to rotate?

Post by pythoncoder » Fri Apr 26, 2019 5:43 pm

I must admit I hadn't considered the case where someone might want to write to a framebuf and then output the result to a separate display instance. I think you'll have to create a dummy display device derived from framebuf and point the Writer at that.

I think the dummy could be along these lines. Note I haven't actually tried this:

Code: Select all

class DummyDisplay(framebuf.FrameBuffer):
    def __init__(self, width, height, mode):
        self.height = height  # your height and width in pixels
        self.width = width
        self.buffer = bytearray(height * width)
        super().__init__(self.buffer, width, height, mode)
Peter Hinch
Index to my micropython libraries.

JumpZero
Posts: 54
Joined: Mon Oct 30, 2017 5:54 am
Location: Arcachon - France

Re: Waveshare e-paper display how to rotate?

Post by JumpZero » Sun Apr 28, 2019 1:14 pm

Hi
@pythoncoder thank you very much for your support. It works! :-)
It took me sometime because I’m not comfortable enough with python class definition (self and super() are still a bit obscure, but I learn!). I had to change some minor things in this DummyDisplay class and this took me time and tries but now I can use bigger fonts.
Here is my code:

Code: Select all

import framebuf
import epaper2in13b
from machine import Pin, SPI
from writer import Writer
import freesans20

sck = Pin(13); mosi = Pin(14); cs = Pin(15); busy = Pin(25); rst = Pin(26); dc = Pin(27); miso = Pin(12)
spi = SPI(baudrate=100000, polarity=0, phase=0, sck=sck, mosi=mosi, miso=miso)
e = epaper2in13b.EPD(spi, cs, dc, rst, busy)
e.init()

class DummyDisplay(framebuf.FrameBuffer):
    def __init__(self, buffer, width, height, format):
        self.height = height
        self.width = width
        self.buffer = buffer
        self.format = format
        super().__init__(buffer, width, height, format)

w=104; h=212
buf_black = bytearray(w * h // 8)
buf_red   = bytearray(w * h // 8)
black_red = 0 # will be black on buf_black, red on buf_red
white     = 1

d_b = DummyDisplay(buf_black, w, h, framebuf.MONO_HLSB)
d_r = DummyDisplay(buf_red, w, h, framebuf.MONO_HLSB)
d_b.fill(white)
d_r.fill(white)

wri_b = Writer(d_b, freesans20, False)
Writer.set_textpos(d_b, 0, 0)  # verbose = False to suppress console output
wri_b.printstring('Sunday\n', True)
wri_b.printstring('28/04/2019\n',True)
wri_b.printstring('14:30', True)

wri_r = Writer(d_r, freesans20, False)
Writer.set_textpos(d_r, 100, 0)
wri_r.printstring('uPython\n', True)
wri_r.printstring('    :-)', True)

print('Sending to display')
e.display_frame(buf_black, buf_red)
print('Done!.......')
e.sleep()  # recommended by manufacturer to avoid damage to display
print('E-paper sleeping!...')

print('END')
Next step will be to use your font-to-py to generate some fonts!
Here is a photo of the result
Image
Thanks again I really appreciate
--
Jmp0

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Waveshare e-paper display how to rotate?

Post by pythoncoder » Mon Apr 29, 2019 6:20 am

Congratulations on getting it working. :D

I strongly recommend getting proficient with Python's object oriented capabilities, either from a book or by following an online course on a PC.
Peter Hinch
Index to my micropython libraries.

JordanDarabos
Posts: 2
Joined: Tue Oct 26, 2021 4:47 am

Re: Waveshare e-paper display how to rotate?

Post by JordanDarabos » Tue Oct 26, 2021 5:39 am

Hello there,

So I've been trying for a couple days to rotate this Waveshare 2.9" E-Paper Module(B/W) and have had no success. I can display text and shapes in portrait mode with no issues. I even made a custom font library using @pythoncoder examples. However, I'm having the hardest time rotating this for some reason. Any help is greatly appreciated. I've stripped down my code to just include what's necessary to run the screen and rotate it. I tried the method JumpZero is using and have had no luck, it just displays a bunch of junk on the screen. Below is my code as it stands now.

Code: Select all

import epaper2in9, time
from machine import SPI, Pin
from writer import Writer
import myfont
import framebuf


spi = SPI(2, baudrate=2000000, polarity=0, phase=0)
cs = Pin(5)
dc = Pin(17)
rst = Pin(16)
busy = Pin(4)

e = epaper2in9.EPD(spi, cs, dc, rst, busy)
e.init()

w = 296
h = 128
x = 0
y = 0


e.clear_frame_memory(b'\xFF')
e.display_frame()

buf = bytearray(w * h // 8)
buf_black = bytearray(w * h // 8)
fb = framebuf.FrameBuffer(buf_black, w, h, framebuf.MONO_VLSB)

fb.fill(1)

fb.text('Hello world!', 0, 0,0)

x=0; y=-1; n=0; m=0
for i in range(0, 16):
    for j in range(0, 296):
        m = (n-x)+(n-y)*15
        buf[m] = buf_black[n]
        n +=1
    x = n+i+1
    y = n-1


e.set_frame_memory(buf, x, y, w, h)
e.display_frame()




User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Waveshare e-paper display how to rotate?

Post by pythoncoder » Tue Oct 26, 2021 10:45 am

Why not try the approach of @JumpZero which has been proven to work? It has the advantage of not requiring explicit rotation. You create a dummy display with a portrait format (w < h) and render text to it. Then simply copy the buffer to the landscape format display.
Peter Hinch
Index to my micropython libraries.

JordanDarabos
Posts: 2
Joined: Tue Oct 26, 2021 4:47 am

Re: Waveshare e-paper display how to rotate?

Post by JordanDarabos » Tue Oct 26, 2021 8:49 pm

pythoncoder wrote:
Tue Oct 26, 2021 10:45 am
Why not try the approach of @JumpZero which has been proven to work? It has the advantage of not requiring explicit rotation. You create a dummy display with a portrait format (w < h) and render text to it. Then simply copy the buffer to the landscape format display.
Hey Pythoncoder,

Thank you for your quick response! If I'm understanding you correctly I have tried to do this and have had no luck getting it to work. You mean swapping the H and W before sending it to the display correct? In the library of this particular screen (2.9") it seems update differently than JumpZeros so that might be causing an issue there. I was able to get something horizontal on the display this with the below code but I'm not quite sure what could be causing the issue. Any direction would be appreciated. Cheers!


Code: Select all

import epaper2in9, time
from machine import SPI, Pin
from writer import Writer
import myfont
import framebuf


spi = SPI(2, baudrate=2000000, polarity=0, phase=0)
cs = Pin(5)
dc = Pin(17)
rst = Pin(16)
busy = Pin(4)

e = epaper2in9.EPD(spi, cs, dc, rst, busy)
e.init()

e.clear_frame_memory(b'\xFF')

class DummyDisplay(framebuf.FrameBuffer):
    def __init__(self, buffer, width, height, format):
        self.height = height
        self.width = width
        self.buffer = buffer
        self.format = format
        super().__init__(buffer, width, height, format)

    def show():
        ...


w = 128
h = 296
start_x = 0
start_y = 0

# --------------------
# # write hello world with black bg and white text
# from onelink_logo import onelink_logo
# e.clear_frame_memory(b'\xFF')
# e.set_frame_memory(onelink_logo, x, y, w, h)
# e.display_frame()
# # --------------------

buf_black = bytearray(w * h // 8)
buf = bytearray(w * h // 8)


d_b = DummyDisplay(buf_black, w, h, framebuf.MONO_VLSB)
d_b.fill(1)

wri = Writer(d_b, myfont)

# verbose = False to suppress console output
Writer.set_textpos(d_b, 0, 0)
wri.printstring('Hello World')

n=0
for i in range(0, 16):
    for j in range(0, 296):
        m = ((j+1) * 16) - (i+1)
        buf[m] = buf_black[n]
        #print(n," -> ",m)
        n +=1

# x=0; y=-1; n=0; m=0
# for i in range(0, 16):
#     for j in range(0, 296):
#         m = (n-x)+(n-y)*15
#         #print(n," -> ",m)
#         buf[m] = buf_black[n]
#         n +=1
#     x = n+i+1
#     y = n-1

# clear
e.set_frame_memory(buf, start_x, start_y, w, h)
e.display_frame()
# --------------------



Image

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Waveshare e-paper display how to rotate?

Post by pythoncoder » Wed Oct 27, 2021 9:07 am

You should be able to copy with something like:

Code: Select all

for n, x in enumerate(buf_black):
    buf[n] = x
However it should be possible to just use one buffer, pointing the display driver at buf_black directly, as @JumpZero did. Note that his code has added complexity because his display is a red/black display which is effectively two displays. But he does no buffer copying, simply pointing the display driver at his red and black buffers.
Peter Hinch
Index to my micropython libraries.

GalUnDrux
Posts: 1
Joined: Wed Jul 13, 2022 4:41 pm

Re: Waveshare e-paper display how to rotate?

Post by GalUnDrux » Wed Jul 13, 2022 5:03 pm

Hey,

Sorry to revive an old thread, I am having similar issues...

I am trying to interface a 1.54" V2 Waveshare e-paper display with a Waveshare RP2040-Zero but I cannot find a compatible driver or any example code to reverse-engineer!

@devnull I too need a rotated display due to hardware layout and constraints..
Did you manage to get this working on the 1.54", do you have a V1 or V2 screen?
If you still have it, any chance you could share your setup code please?
JumpZero wrote:
Thu Apr 25, 2019 12:48 pm
Hi!
@devnull:
You can try this code, it's adapted from my 104x212 to your 200x200, maybe I've done some typo. I cannot test it since I don't have a 200x200 e-paper display. If yours is black only remove all lines with reference to red. It may give you a path to follow even if doesn't work out of the box ;-)
The algorithm is the one I use, I've just changed some figures.
You have to add all your init and spi stuff..

Code: Select all

h = 200;  w = 200 # e-paper heigth and width.

buf_black        = bytearray(w * h // 8) # used by frame buffer (landscape)
buf_red          = bytearray(w * h // 8) # used by frame buffer (landscape)
buf_epaper_black = bytearray(w * h // 8) # used to display on e-paper after bytes have been
buf_epaper_red   = bytearray(w * h // 8) # moved from frame buffer to match e-paper (portrait)

import framebuf
fb_black = framebuf.FrameBuffer(buf_black, w, h, framebuf.MONO_VLSB)
fb_red   = framebuf.FrameBuffer(buf_red,   w, h, framebuf.MONO_VLSB)
black_red = 0 # will be black on buf_black, red on buf_red
white     = 1

#clear red & black screens, write in black on top left and in red bootom right
fb_black.fill(white)
fb_red.fill(white)
fb_black.text('Hello world!', 0, 0,black_red)
fb_red.text('Hello world!', 110, 90,black_red)

# Move frame buffer bytes to e-paper buffer to match e-paper bytes oranisation.
# That is landscape mode to portrait mode. (for red and black buffers)
for i in range(0, 25):
    for j in range(0, 200):
        m = (n-x)+(n-y)*24
        buf_epaper_black[m] = buf_black[n]
        buf_epaper_red[m] = buf_red[n]
        n +=1
    x = n+i+1
    y = n-1

print('Sending to display')
e.display_frame(buf_epaper_black, buf_epaper_red)
print('Done!.......')
Thank you!

McRaceface
Posts: 1
Joined: Sat Jul 16, 2022 8:17 pm

Re: Waveshare e-paper display how to rotate?

Post by McRaceface » Sat Jul 16, 2022 8:20 pm

GalUnDrux wrote:
Wed Jul 13, 2022 5:03 pm
but I cannot find a compatible driver or any example code to reverse-engineer!
Would this help? https://github.com/waveshare/e-Paper/bl ... V2_test.py

Post Reply