rm-hull / luma.lcd

Python module to drive PCD8544, HT1621, ST7735, ST7567 and UC1701X-based LCDs
https://luma-lcd.readthedocs.io
MIT License
156 stars 56 forks source link

ST7735 inverted colors #115

Closed jackjameshoward closed 3 years ago

jackjameshoward commented 3 years ago

I'm following on from issue #79 which has now been merged.

I bought a similar LCD display from pimoroni Works great, however, if I run python3 examples/colors.py -f conf/st7735.conf the colours are inverted. For 'red' I get yellow, 'green' turns magenta, etc. Same goes for any example, not just color.py.

And I have no idea what the --bgr flag does but it didn't make a difference for me.

For this display I changed the conf file to

--display=st7735
--interface=spi
--spi-bus-speed=16000000
--gpio-data-command=9
--gpio-backlight=19
--width=160
--height=80
--backlight-active=high
--spi-cs-high=true
--spi-device=1
--v-offset=26
--h-offset=1

Does anybody have a suggestion? Thanks

rm-hull commented 3 years ago

The --bgr flag will swap the red and blue primary colors - some devices are mapped differently.

However if you are seeing yellow instead of red, and magenta instead of green this suggests that the color palette on your device is not wide enough to cater for 262k colors (see https://github.com/rm-hull/luma.lcd/blob/master/luma/lcd/device.py#L304)

Looking at the recommended/supported driver from pimoroni they squash the color palette into 16 bits (5-6-5) whereas the luma driver uses 18 bits (6-6-6). See https://github.com/pimoroni/st7735-python/blob/master/library/ST7735/__init__.py#L112. I would guess this is the root cause of the problem...

So the simple answer is that there is no simple fix right now. We could add support but I don’t have a device to test against, so one option is try and fix it yourself and submit a PR, another would be to loan/donate me a display so I could investigate further ... alternatively we could appeal to @Gadgetoid (author/maintainer of the pimoroni driver) who might be inclined to supply a PR to luma.lcd

jackjameshoward commented 3 years ago

I found what I needed. https://github.com/rm-hull/luma.lcd/blob/master/luma/lcd/device.py#L373 Display inversion needs to be on 0x21. I looked into the difference 16bit (5-6-5) vs 18bit (6-6-6) and it looks like you can select either mode during the init , pimoroni have their color mode set to 0x05 (5-6-5) whereas luma is 0x06 (6-6-6). The ST7735 can handle either format.

I have just changed my device.py locally to select color inversion. I'm not sure if there is a cmd arg for this?

jackjameshoward commented 3 years ago

It looks like the issue I'm having has been solved before here #105, it just hasn't made it to master yet.

thijstriemstra commented 3 years ago

Let's keep the ticket open till it's fixed in master.

thijstriemstra commented 3 years ago

@jackjameshoward can you test with master?

jackjameshoward commented 3 years ago

I think i've done something incorrectly. I cloned the repo and ran the setup.py. Now it looks as though it's doesn't find any lcd modules.

pi@raspberrypi:~ $ git clone https://github.com/rm-hull/luma.lcd.git
Cloning into 'luma.lcd'...

remote: Enumerating objects: 184, done.
remote: Counting objects: 100% (184/184), done.
remote: Compressing objects: 100% (127/127), done.
remote: Total 1337 (delta 108), reused 120 (delta 57), pack-reused 1153
Receiving objects: 100% (1337/1337), 16.48 MiB | 2.04 MiB/s, done.
Resolving deltas: 100% (770/770), done.
pi@raspberrypi:~ $ cd luma.lcd
pi@raspberrypi:~/luma.lcd $ sudo -H pip3 install -e .
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Obtaining file:///home/pi/luma.lcd
Requirement already satisfied: luma.core>=1.16.2 in /usr/local/lib/python3.7/dist-packages (from luma.lcd==2.5.0) (1.16.2)
Requirement already satisfied: pillow>=4.0.0 in /usr/lib/python3/dist-packages (from luma.core>=1.16.2->luma.lcd==2.5.0) (5.4.1)
Requirement already satisfied: cbor2 in /usr/local/lib/python3.7/dist-packages (from luma.core>=1.16.2->luma.lcd==2.5.0) (5.1.2)
Requirement already satisfied: smbus2 in /usr/local/lib/python3.7/dist-packages (from luma.core>=1.16.2->luma.lcd==2.5.0) (0.3.0)
Requirement already satisfied: pyftdi in /usr/local/lib/python3.7/dist-packages (from luma.core>=1.16.2->luma.lcd==2.5.0) (0.51.2)
Requirement already satisfied: spidev<=3.4; platform_system == "Linux" in /usr/lib/python3/dist-packages (from luma.core>=1.16.2->luma.lcd==2.5.0) (3.4)
Requirement already satisfied: RPI.GPIO; platform_system == "Linux" in /usr/lib/python3/dist-packages (from luma.core>=1.16.2->luma.lcd==2.5.0) (0.7.0)
Requirement already satisfied: pyserial>=3.0 in /usr/lib/python3/dist-packages (from pyftdi->luma.core>=1.16.2->luma.lcd==2.5.0) (3.4)
Requirement already satisfied: pyusb>=1.0.0 in /usr/local/lib/python3.7/dist-packages (from pyftdi->luma.core>=1.16.2->luma.lcd==2.5.0) (1.1.0)
Installing collected packages: luma.lcd
  Found existing installation: luma.lcd 2.4.0
    Uninstalling luma.lcd-2.4.0:
      Successfully uninstalled luma.lcd-2.4.0
  Running setup.py develop for luma.lcd
Successfully installed luma.lcd
pi@raspberrypi:~/luma.lcd $ cd
pi@raspberrypi:~ $ cd luma.examples
pi@raspberrypi:~/luma.examples $ python3 examples/colors.py -f conf/st7735_pim.conf
usage: colors.py [-h] [--config CONFIG] [--display DISPLAY] [--width WIDTH]
                 [--height HEIGHT] [--rotate ROTATION] [--interface INTERFACE]
                 [--i2c-port I2C_PORT] [--i2c-address I2C_ADDRESS]
                 [--spi-port SPI_PORT] [--spi-device SPI_DEVICE]
                 [--spi-bus-speed SPI_BUS_SPEED] [--spi-cs-high SPI_CS_HIGH]
                 [--spi-transfer-size SPI_TRANSFER_SIZE]
                 [--ftdi-device FTDI_DEVICE] [--gpio GPIO]
                 [--gpio-mode GPIO_MODE]
                 [--gpio-data-command GPIO_DATA_COMMAND]
                 [--gpio-reset GPIO_RESET] [--gpio-backlight GPIO_BACKLIGHT]
                 [--block-orientation ORIENTATION] [--mode MODE]
                 [--framebuffer FRAMEBUFFER] [--bgr] [--h-offset H_OFFSET]
                 [--v-offset V_OFFSET] [--backlight-active VALUE]
                 [--transform TRANSFORM] [--scale SCALE] [--duration DURATION]
                 [--loop LOOP] [--max-frames MAX_FRAMES]
colors.py: error: argument --display/-d: invalid choice: 'st7735' (choose from 'ssd1306', 'ssd1309', 'ssd1322', 'ssd1362', 'ssd1322_nhd', 'ssd1325', 'ssd1327', 'ssd1331', 'ssd1351', 'sh1106', 'max7219', 'ws2812', 'neopixel', 'neosegment', 'apa102', 'unicornhathd', 'capture', 'gifanim', 'pygame', 'asciiart', 'asciiblock')

The contents of my conf file is

--display=st7735
--interface=spi
--spi-bus-speed=16000000
--gpio-data-command=9
--gpio-backlight=19
--width=160
--height=80
--backlight-active=high
--spi-cs-high=true
--spi-device=1
--v-offset=26
--h-offset=1
--bgr
--inverse

I did check to see if the module is recognised by pip3

pi@raspberrypi:~/luma.examples $ pip3 show luma.lcd
Name: luma.lcd
Version: 2.5.0
Summary: A library to drive PCD8544, HT1621, ST7735, ST7567, UC1701X and ILI9341-based LCDs
Home-page: https://github.com/rm-hull/luma.lcd
Author: Richard Hull
Author-email: richard.hull@destructuring-bind.org
License: MIT
Location: /home/pi/luma.lcd
Requires: luma.core
Required-by: luma.examples

and I also tried to manually import it

pi@raspberrypi:~/luma.examples $ python3
Python 3.7.3 (default, Jul 25 2020, 13:03:44) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from luma.lcd.device import st7735
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/pi/luma.lcd/luma/lcd/device.py", line 47, in <module>
    from luma.core.bitmap_font import embedded_fonts
  File "/usr/local/lib/python3.7/dist-packages/luma/core/bitmap_font.py", line 8, in <module>
    from PIL import Image, ImageFont, UnidentifiedImageError
ImportError: cannot import name 'UnidentifiedImageError' from 'PIL' (/usr/lib/python3/dist-packages/PIL/__init__.py)

I figured there was a problem with PIL so I tried

pi@raspberrypi:~/luma.examples $ sudo apt-get install python3-pil
Reading package lists... Done
Building dependency tree       
Reading state information... Done
python3-pil is already the newest version (5.4.1-2+deb10u2).
python3-pil set to manually installed.
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

@thijstriemstra do you have any suggestions?

dhrone commented 3 years ago

It does look like something is messed up with your pillow installation.

Could you look at the contents of /usr/lib/python3/dist-packages/PIL/__init__.py?

The bottom of that file should contain...

class UnidentifiedImageError(OSError):
    """
    Raised in :py:meth:`PIL.Image.open` if an image cannot be opened and identified.
    """

    pass

which is the class that is attempting to be imported when the error occurs.

thijstriemstra commented 3 years ago

@dhrone he's using an really old version of Pillow:

python3-pil is already the newest version (5.4.1-2+deb10u2).

We need to bump the minimum Pillow version to one that has UnidentifiedImageError.

thijstriemstra commented 3 years ago

We now require >= 4.0 (of top of my head) so that 5.4.1 is accepted, but it shouldn't. This probably only needs to be updated in luma.core.

thijstriemstra commented 3 years ago

@jackjameshoward try sudo -H pip3 install -U Pillow

dhrone commented 3 years ago

Yes. Unfortunately, it is what buster is vending when you install python-pil. I had pointed people toward python-pil in the documentation I just updated. We may want to revert that.

I wonder why they are distributing such an old version.

thijstriemstra commented 3 years ago

We may want to revert that.

It pulls in all additional pillow dependencies though, which is useful. If we just make sure luma.core always updates Pillow it should be fine.

dhrone commented 3 years ago

It looks like the UnidentifiedImageError class was added in major release 7. We can make the change to setup.py for luma.core to enforce pillow>=7.0.0. I could also revise luma.core.bitmap_font to support versions using the older code. The only difference appears to be that IOError is used instead of UnidentifiedImageError.

thijstriemstra commented 3 years ago

I could also revise luma.core.bitmap_font to support versions using the older code.

What do you say @rm-hull?

jackjameshoward commented 3 years ago

@jackjameshoward try sudo -H pip3 install -U Pillow

Yes, updating Pillow worked. And the --inverse flag works now too.

jackjameshoward commented 3 years ago

If it any use I can push my config file to new branch? It is for the pimoroni product and it is wired as specfied in the product description. Or for future referece I made a new file st7735_pim.conf

--display=st7735
--interface=spi
--spi-bus-speed=16000000
--gpio-data-command=9
--gpio-backlight=19
--width=160
--height=80
--backlight-active=high
--spi-cs-high=true
--spi-device=1
--v-offset=26
--h-offset=1
--bgr
--inverse
thijstriemstra commented 3 years ago

If it any use I can push my config file to new branch?

You can add it to the luma.examples repository, in the conf directory. Closing this, it'll be in the next luma.lcd release.

rm-hull commented 3 years ago

I could also revise luma.core.bitmap_font to support versions using the older code.

What do you say @rm-hull?

sorry for non-reply, ... i get so many notifications from github that they often get classified as spam and end up in the junk folder.

@jackjameshoward I'll add your conf file to the examples repo