Closed polygonfuture closed 1 year ago
There are potentially two ways to do rotation. One is by sending commands to the driver chip and the other way is by adapting the code that outputs the frame buffer to the chip. The first requires studying the datasheet to find out what is supported. The second is fairly straightforward for 180°: you need to output rows in reverse order and also reverse the order in which pixels are output to columns.
For modifying the framebuffer, would this be done within the show() function within the ssd1351_16bit.py for example?
The .show()
method would perform the rotation. The method of transferring the data to the SPI bus would be adapted to output rows and columns in the correct order.
I solved this issue sending a command to the SSD1351 driver chipset in the SSD1351 python driver. For me this was the ssd1351_16bit.py file in the __init__
section.
As peter mentioned, the datasheet has a command table for a byte command to send to the SSD1351 chipset. The chipset I have is manufactured by Solomon Systech.
You send a Set Re-Map command listed on page 32 of the datasheet.
Based on the table, you do this with two commands, the first tells the chipset we are going to send a Set Remap command. With this command we send a 7 bit value that controls 6 different functions on the SSD1351.
self._write(b'\xA0', 0)
self.write(b'\x76', 1)
In my case I used 0x76 which translates to 01110110 command in the table. Each binary bit represents a specific command the chipset interprets. This correctly flips columns and rows to give a 180 degree visual rotation from the user perspective.
The updated SSD1351 class now reads:
class SSD1351(framebuf.FrameBuffer):
# Convert r, g, b in range 0-255 to a 16 bit colour value RGB565
# acceptable to hardware: rrrrrggggggbbbbb
@staticmethod
def rgb(r, g, b):
return ((r & 0xf8) << 5) | ((g & 0x1c) << 11) | (b & 0xf8) | ((g & 0xe0) >> 5)
def __init__(self, spi, pincs, pindc, pinrs, height=128, width=128, init_spi=False):
if height not in (96, 128):
raise ValueError('Unsupported height {}'.format(height))
self.spi = spi
self.spi_init = init_spi
self.pincs = pincs
self.pindc = pindc # 1 = data 0 = cmd
self.height = height # Required by Writer class
self.width = width
mode = framebuf.RGB565
self.palette = BoolPalette(mode)
gc.collect()
self.buffer = bytearray(self.height * self.width * 2)
super().__init__(self.buffer, self.width, self.height, mode)
self.mvb = memoryview(self.buffer)
pinrs(0) # Pulse the reset line
utime.sleep_ms(1)
pinrs(1)
utime.sleep_ms(1)
if self.spi_init: # A callback was passed
self.spi_init(spi) # Bus may be shared
# See above comment to explain this allocation-saving gibberish.
self._write(b'\xfd\x12\xfd\xb1\xae\xb3\xf1\xca\x7f\xa0\x74'\
b'\x15\x00\x7f\x75\x00\x7f\xa1\x00\xa2\x00\xb5\x00\xab\x01'\
b'\xb1\x32\xbe\x05\xa6\xc1\xc8\x80\xc8\xc7\x0f'\
b'\xb4\xa0\xb5\x55\xb6\x01\xaf', 0)
self._write(b'\xA0',0) #SET REMAP COMMAND
self._write(b'\x76',1) #SEND 7 BIT COMMAND IN HEX FORMAT THAT FLIPS DISPLAY. IN BINARY: 01110110
self.show()
gc.collect()
Thanks for posting this, it is a useful resource if the requirement crops up again.
I'm working with a Waveshare 1.27" rgb OLED screen (128 x 96) that uses the ssd1351 driver. I, too, needed to rotate the display 180 degrees, but when I tried polygonfuture's mod for the driver, things did not quite work correctly. I dug around in the same datasheet and came up with a fix: In addition to polygonfuture's two mod lines, I added the following which alters the Display Start Line (top of page 33 of the datasheet):
self._write(b'\xA1',0) # set command: 'Set Display Start Line'
self._write(b'\x60',1) # set start line to 96
Peter, I see you've marked this closed, but I hope you can add this fix to the thread.
And a huge thank you for nanogui and your other fantastic micropython libraries. They make working with micropython the absolute best.
-tim
Hi Peter, Thank you so much for your work on these libraries.
I'm looking to rotate the SSD1351 by 180 degrees (for a physically upside down display).
I noticed 1327 has the ability to be rotated. Though its driver looks in some ways more simplified / abstracted compared to SSD1351.
Do you have a suggestion of how I might achieve a 180 rotation of a 1351 OLED RGB screen? (Its 16bit color model).