The direction of framebuf.MONO_HLSB

Discussion about programs, libraries and tools that work with MicroPython. Mostly these are provided by a third party.
Target audience: All users and developers of MicroPython.
Post Reply
meebox
Posts: 2
Joined: Sat Feb 01, 2020 4:41 am

The direction of framebuf.MONO_HLSB

Post by meebox » Sat Feb 01, 2020 6:31 am

In the document of framebuf.MONO_HLSB says
Monochrome (1-bit) color format This defines a mapping where the bits in a byte are horizontally mapped. Each byte occupies 8 horizontal pixels with bit 0 being the leftmost.
But it seems to be wrong. Let's take the 8x8 image show bellow for example

Image

If the bit 0 is leftmost one, the bytearray should be

Code: Select all

[0b10001001,
0b00001001,
0b00001001,
0b00001001.
0b00001001.
0b00000001,
0b00000001,
0b00000001]
But this would make the image flip horizontally.Am I right or I misunderstand the document?

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

Re: The direction of framebuf.MONO_HLSB

Post by pythoncoder » Sat Feb 01, 2020 8:43 am

It does seem that the docs have MONO_HMSB and MONO_HLSB transposed. In each case the code below sets the leftmost bit:

Code: Select all

b = bytearray(32)
f = framebuf.FrameBuffer(b, 32, 8, framebuf.MONO_HLSB)
f.pixel(0, 0, 1)
print('MONO_HLSB', hex(b[0]))

b = bytearray(32)
f = framebuf.FrameBuffer(b, 32, 8, framebuf.MONO_HMSB)
f.pixel(0, 0, 1)
print('MONO_HMSB', hex(b[0]))
Result:
MONO_HLSB 0x80
MONO_HMSB 0x1
So in MONO_HLSB bit 7 is the leftmost.
This seems to be confirmed by looking at the source.
Peter Hinch

meebox
Posts: 2
Joined: Sat Feb 01, 2020 4:41 am

Re: The direction of framebuf.MONO_HLSB

Post by meebox » Mon Feb 03, 2020 9:37 am

Thanks.

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

Re: The direction of framebuf.MONO_HLSB

Post by pythoncoder » Sun Feb 09, 2020 4:11 pm

I have raised this PR. A bit embarrassing considering I wrote that part of the doc :oops:
Peter Hinch

User avatar
mcauser
Posts: 437
Joined: Mon Jun 15, 2015 8:03 am

Re: The direction of framebuf.MONO_HLSB

Post by mcauser » Mon Feb 10, 2020 1:13 pm

You're right. LSB+MSB are reversed. :shock:

In HLSB mode, the first pixel written [#.......] is the least significant bit in the byte 0x01.

Consider these examples:

Code: Select all

import framebuf
b = bytearray(16)
f = framebuf.FrameBuffer(b, 16, 8, framebuf.MONO_HLSB)
f.text('FR',0,0,1)

b == bytearray(b'\x7E\x7C\x60\x66\x60\x66\x78\x7C\x60\x78\x60\x6C\x60\x66\x00\x00')

0b01111110, 0b01111100, // .######...#####.
0b01100000, 0b01100110, // .....##..##..##.
0b01100000, 0b01100110, // .....##..##..##.
0b01111000, 0b01111100, // ...####...#####.
0b01100000, 0b01111000, // .....##....####.
0b01100000, 0b01101100, // .....##...##.##.
0b01100000, 0b01100110, // .....##..##..##.
0b00000000, 0b00000000, // ................

Code: Select all

import framebuf
b = bytearray(16)
f = framebuf.FrameBuffer(b, 16, 8, framebuf.MONO_HMSB)
f.text('FR',0,0,1)

b == bytearray(b'\x7E\x3E\x06\x66\x06\x66\x1E\x3E\x06\x1E\x06\x36\x06\x66\x00\x00')

0b01111110, 0b00111110, // .######...#####.
0b00000110, 0b01100110, // .....##..##..##.
0b00000110, 0b01100110, // .....##..##..##.
0b00011110, 0b00111110, // ...####...#####.
0b00000110, 0b00011110, // .....##....####.
0b00000110, 0b00110110, // .....##...##.##.
0b00000110, 0b01100110, // .....##..##..##.
0b00000000, 0b00000000, // ................
Both of the buffers byte arrays when visualised are backwards.

In VLSB mode, the first pixel written is the least significant bit in the byte 0x01:
#
.
.
.
.
.
.
.
Last edited by mcauser on Mon Feb 10, 2020 2:02 pm, edited 3 times in total.

User avatar
mcauser
Posts: 437
Joined: Mon Jun 15, 2015 8:03 am

Re: The direction of framebuf.MONO_HLSB

Post by mcauser » Mon Feb 10, 2020 1:46 pm

Also, there are two horizontals and verticals. Pixel orientation and byte progression.

The current mono HLSB, HMSB, VMSB only support horizontal progression. Each byte steps to the right then wraps.
The H and V in these formats represent the pixel orientation. Whether it's a tower of 8 pixels tall in vertical, or pancake of 8 pixels wide in horizontal modes.

The Nokia 5110 aka PCD8544 driver supports horizontal and vertical modes, however this is the byte progression, not the pixel orientation.
Each byte is always a tower of 8 pixels.
https://github.com/mcauser/micropython- ... addressing
There's currently no support for vertical mode as there's no compatible framebuf format (vertical col major msb).

Another name for the byte progression is row and column major ordering
https://en.wikipedia.org/wiki/Row-_and_ ... ajor_order
If you write one byte at a time, do they go down then wrap across, or across then wrap down.

Some display drivers, such as the SSD1306, support remapping the segments too, which is like a flip-x and setting the com scan direction.
The ST7735 gives you three options, mirror-x, mirror-y and scan direction.
These options, along with choosing an appropriate framebuf format allow for device rotation.

Sounds like I need to write a bunch of tests.

fxmike08
Posts: 1
Joined: Wed Feb 05, 2020 1:01 pm

Re: The direction of framebuf.MONO_HLSB

Post by fxmike08 » Mon Feb 10, 2020 3:57 pm

I having same behavior on a 2.13" display, having a IL3897 driver http://www.e-paper-display.com/download ... 82&v=0.zip. This driver doesn't seems to be supported yet by any micropython library. I added a solution for this on https://github.com/mcauser/micropython- ... -583885644

Image
According to IL3897 datasheet there is a "Data Entry mode setting", but I had no luck in changing that behavior. I don't know what I'm missing.

Code: Select all

import framebuf
buf = bytearray(128 * 250 // 8)
fb = framebuf.FrameBuffer(buf, 128, 250, framebuf.MONO_HLSB)
black = 0
white = 1
fb.fill(white)
fb.text('Hello World',30,10,black)
fb.pixel(30, 10, black)
fb.hline(30, 30, 10, black)
fb.vline(30, 50, 10, black)
fb.line(30, 70, 40, 80, black)
fb.rect(30, 90, 10, 10, black)
fb.fill_rect(30, 110, 10, 10, black)
for row in range(0,37):
	fb.text(str(row),0,row*8,black)
fb.text('Line 36',0,288,black)
e.displayBuffer(buf)

If I'm changing to framebuf.MONO_VLSB the displayed image is not readable (some random lines).
I'm using Micropython v1.11.

My intention is to display the content in landscape mode. Any idea how to switch it to landscape and not being mirrored ? Thanks

Post Reply