rm-hull / luma.lcd

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

Trying to get this to work with Spotpear LCD #139

Closed jason-a69 closed 3 years ago

jason-a69 commented 3 years ago

This is my lcd http://www.spotpear.com/index.php/index/study/detail/id/77.html

Type of Raspberry Pi

Raspberry Pi 3A

Linux Kernel version

Linux raspberrypi 5.4.79-v7+ #1373 SMP Mon Nov 23 13:22:33 GMT 2020 armv7l GNU/Linux

Expected behaviour

I expect a 3d box

Actual behaviour

Trying to get the display to work with the correct driver If I try and run 3d_box.py I get the following error message

3d_box.py: error: I2C device not found on address: 0x3C

This is no surprise as i2cdetect 1

Does not report anything, I get 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

Does anyone have any pointers please?

CRImier commented 3 years ago

first quick note - your LCD is not I2C, is SPI, so you need to let the driver know how to correctly reach your display - through the correct SPI port, using the right SPI settings and right GPIO pins. You should be able to get all of these parameters from the example code they're providing.

jason-a69 commented 3 years ago

Unfortunately, there is only one c program that you can download (to create fbcp) and I did not find it very helpful.

I did some digging around in /sys with find /sys/bus | grep spi

and got this back

/sys/bus/platform/devices/3f204000.spi /sys/bus/platform/drivers/spi-bcm2835 /sys/bus/platform/drivers/spi-bcm2835/bind /sys/bus/platform/drivers/spi-bcm2835/unbind /sys/bus/platform/drivers/spi-bcm2835/module /sys/bus/platform/drivers/spi-bcm2835/uevent /sys/bus/platform/drivers/spi-bcm2835/3f204000.spi /sys/bus/spi /sys/bus/spi/drivers_probe /sys/bus/spi/devices /sys/bus/spi/devices/spi0.0 /sys/bus/spi/devices/spi0.1 /sys/bus/spi/uevent /sys/bus/spi/drivers /sys/bus/spi/drivers/stmpe-spi /sys/bus/spi/drivers/stmpe-spi/bind /sys/bus/spi/drivers/stmpe-spi/unbind /sys/bus/spi/drivers/stmpe-spi/uevent /sys/bus/spi/drivers/fb_ili9340 /sys/bus/spi/drivers/fb_ili9340/spi0.0 /sys/bus/spi/drivers/fb_ili9340/bind /sys/bus/spi/drivers/fb_ili9340/unbind /sys/bus/spi/drivers/fb_ili9340/module /sys/bus/spi/drivers/fb_ili9340/uevent /sys/bus/spi/drivers/ads7846 /sys/bus/spi/drivers/ads7846/bind /sys/bus/spi/drivers/ads7846/unbind /sys/bus/spi/drivers/ads7846/spi0.1 /sys/bus/spi/drivers/ads7846/module /sys/bus/spi/drivers/ads7846/uevent /sys/bus/spi/drivers_autoprobe

So it is using the fb_ili9340 driver, that source code is here https://github.com/adafruit/adafruit-rpi-fbtft/blob/master/fb_ili9340.c

Can I extract the correct information from there?

CRImier commented 3 years ago

There's still some information in the linked repo, specifically, the script that you're advised to use. The script uses the waveshare32b overlay from their repository, which is compiled. It's scummy from their side not to publish sources for the overlay, however, overlays are easy to decompile into a state where you can see the pins used:

dtc -I dtb -O dts -o waveshare35b-overlay.dts waveshare35b-overlay.dtb
/dts-v1/;

/ {
    compatible = "brcm,bcm2835\0brcm,bcm2708\0brcm,bcm2709";

    [...]

    fragment@1 {
        target = <0xffffffff>;

        __overlay__ {

            waveshare35b_pins {
                brcm,pins = <0x11 0x19 0x18>;
                brcm,function = <0x00 0x00 0x00>;
                phandle = <0x01>;
            };
        };
    };

    fragment@2 {
        target = <0xffffffff>;

        __overlay__ {
            #address-cells = <0x01>;
            #size-cells = <0x00>;

            waveshare35b@0 {
                compatible = "ilitek,ili9486";
                reg = <0x00>;
                pinctrl-names = "default";
                pinctrl-0 = <0x01>;
                spi-max-frequency = <0xe4e1c0>;
                txbuflen = <0x8000>;
                rotate = <0x5a>;
                bgr = <0x00>;
                fps = <0x1e>;
                buswidth = <0x08>;
                regwidth = <0x10>;
                reset-gpios = <0xffffffff 0x19 0x01>;
                dc-gpios = <0xffffffff 0x18 0x00>;
                debug = <0x00>;
                init = <0x10000b0 0x00 0x1000011 0x20000ff 0x100003a 0x55 0x1000036 0x28 0x1000021 0x10000c0 0x09 0x09 0x10000c1 0x41 0x00 0x10000c5 0x00 0x36 0x10000e0 0x00 0x2c 0x2c 0x0b 0x0c 0x04 0x4c 0x64 0x36 0x03 0x0e 0x01 0x10 0x01 0x00 0x10000e1 0x0f 0x37 0x37 0x0c 0x0f 0x05 0x50 0x32 0x36 0x04 0x0b 0x00 0x19 0x14 0x0f 0x1000011 0x20000ff 0x1000029>;
                phandle = <0x02>;
            };

            waveshare35b-ts@1 {
                compatible = "ti,ads7846";
                reg = <0x01>;
                spi-max-frequency = <0x1e8480>;
                interrupts = <0x11 0x02>;
                interrupt-parent = <0xffffffff>;
                pendown-gpio = <0xffffffff 0x11 0x01>;
                ti,x-plate-ohms = [00 3c];
                ti,pressure-max = [00 ff];
                phandle = <0x03>;
            };
        };
    };

    __overrides__ {
        speed = <0x02 0x7370692d 0x6d61782d 0x66726571 0x75656e63 0x793a3000>;
        txbuflen = [00 00 00 02 74 78 62 75 66 6c 65 6e 3a 30 00];
        rotate = [00 00 00 02 72 6f 74 61 74 65 3a 30 00];
        fps = [00 00 00 02 66 70 73 3a 30 00];
        bgr = [00 00 00 02 62 67 72 3a 30 00];
        debug = <0x02 0x64656275 0x673a3000>;
        swapxy = <0x03 0x74692c73 0x7761702d 0x78793f00>;
    };

    [...]
};

Full decompiled overlay sources: waveshare35b-overlay.zip

The pins used for RST/DC should be easy to understand. Let me think for a second where we can go from here...

CRImier commented 3 years ago

For a start, the RST pin should be 25 and DC pin should be 24.

CRImier commented 3 years ago

image lol, Spotpear seems to be a shitty company when it comes to open-sourcing even the most primitive stuff, not to mention even schematics. Would not be surprised if there's no original work put from their side, their products seem to be similar to Waveshare products, at least they're reusing the code and the overlays...

Wait, are they by any chance the same company? =D Now I'm getting confused who's doing which part, either way, would not be surprised to hear that they are in fact the same. Enough about that - did anyone in this repo try and make a Waveshare display similar to yours working?

Yep! Check this out, this might just help you a lot: https://github.com/rm-hull/luma.lcd/pull/136

jason-a69 commented 3 years ago

Thanks for all of this, much appreciated.

You should see Spotpear's attempt at scripts, no formatting whatsoever, no subtle stuff like injecting parameters into configuration files. Oh no, just overwrite the files instead. My favourite is overwriting /boot/config.txt.

Anyway, I am still trying to get a successful test working, I am running this python3 3d_box.py -i spi --gpio-reset 25 --gpio-data-command 24 -d ili9486 --spi-device 1

I am getting this error /usr/local/lib/python3.7/dist-packages/luma/core/interface/serial.py:200: RuntimeWarning: This channel is already in use, continuing anyway. Use GPIO.setwarnings(False) to disable warnings.

fbcp is not running.

I tried to run test_ili9486.py and it did not return anything.

Any clues please?

CRImier commented 3 years ago

do you have the overlay loaded? make sure it's not loaded.

This warning is likely expected and normal - the display should work nevertheless. What actually happens instead? You're not describing the result you're getting.

CRImier commented 3 years ago

hmm, sorry, I'm on the go. What does --spi-device mean? I'd imagine the display is connected to SPI0.0 and touch is connected to SPI0.1 - that's been my experience with the display I have, but it might not be the case with whatever breakout you're trying out. Or is it something other than SPI port/SPI CS number?

CRImier commented 3 years ago

also, it's no wonder test_ili9486.py returns nothing - it actually isn't written to operate on a real display, it's just a luma test file that helps luma developers check whether the code is still working.

jason-a69 commented 3 years ago

OK. I have removed dtoverlay=waveshare32b:rotate=270 from /boot/config.txt

The following devices are created

/dev/spidev0.0
/dev/spidev0.1

I have rerun with python3 3d_box.py -i spi --gpio-reset 25 --gpio-data-command 24 -d ili9486

I get 3d_box.py: error: Unsupported display mode: 128 x 64

So I am getting closer!

CRImier commented 3 years ago

seems like you need to give it height and width parameters =)

jason-a69 commented 3 years ago

I tried --width 320 --height 240

Got 3d_box.py: error: Unsupported display mode: 320 x 240

All I have is a white screen....it must be something simple

CRImier commented 3 years ago

searching "ili9486" in this repo on github brought me to this page, which says that only 480x320 displays are supported at the moment. Are you sure your display is 320x240?

jason-a69 commented 3 years ago

Unfortunately it is 320 x 240

jason-a69 commented 3 years ago

If I make a change in that code to take out that check (in device.py) do I have to recompile it?

CRImier commented 3 years ago

Good thinking! Answering your question directly - no, but you'll have to make sure that your changes actually get used by your scripts, i.e. git-clone-ing this code locally, making your changes then using something like python setup.py develop to install the locally-modified library - or just edit the library files in the place they're currently stored after you install using pip.

Answering the bigger question - the check is there for a reason. First of all, it's a sanity check of whether a known-valid width&height pair is passed, but also, it's a check to see whether the library has actually been tested with the display in question. The library code adapts to different widths and heights when it comes to i.e. graphics primitives and so on, but there's one more thing you might want to keep in mind - some initialization commands will be different depending on the display size (width&height in pixels), as displays of different size, even if they use the same controller for driving the panel's pixels, will wire the panel differently and might have a lot of tiny but significant bits&pieces configured in a different way, to the point of no image appearing on the display.

What can you do about this if simply removing the width&height check will not work? The major thing is checking initialization commands against ones from a library that's known-good and works for your display, then using them. Order of the commands will be different and that's okay. After you do this, the display should work. Next step would be to contribute your changes to this repository so that everyone interested would be able to use them, and as such, make the world a bit of a brighter place =)

What you can also do is use the overlay (that seems to actually work for you), not enable fbcp and instead use the luma's linux-framebuffer support to draw to the /dev/fb1 device created by the display driver. If you don't want to play with adjusting init commands, this would probably be the easiest solution for you.

jason-a69 commented 3 years ago

I figured out how to remove luma.lcd and make changes to a locally cloned copy (in /home/pi) and install that.

Just sharing here if anyone is curious First part solution : sudo pip3 uninstall luma.lcd Second part solution : sudo pip3 install -e /home/pi/luma.lcd

I just want to remove the check to see if anything is displayed, I am still looking at a white screen even though this command now runs. python3 luma.examples/examples/3d_box.py --interface spi -d ili9486 --width 320 --height 240

If I put dtoverlay=waveshare32b:rotate=270 back into /boot/config.txt I get a black screen. If I try to run python3 luma.examples/examples/3d_box.py --interface spi --gpio-reset 25 --gpio-data-command 24 -d ili9486 --width 320 --height 240 --framebuffer-device /dev/fb1

I get

/usr/local/lib/python3.7/dist-packages/luma/core/interface/serial.py:200: RuntimeWarning: This channel is already in use, continuing anyway.  Use GPIO.setwarnings(False) to disable warnings.
  self._gpio.setup(pin, self._gpio.OUT)

I will share my efforts when I get this working :) I also understand why sanity checks are put into code, I will put them back once I get something displayed.

jason-a69 commented 3 years ago

Finally got it running

python3 luma.examples/examples/3d_box.py --interface spi --gpio-reset 25 --gpio-data-command 24 -d linux_framebuffer --width 320 --height 240 --framebuffer-device /dev/fb1

No code changes required, just pass the correct parameters!

CRImier commented 3 years ago

happy to hear that! It's not even clear to me that you need the SPI and GPIO parameters, I'd bet they're just unused, try removing them and my hunch is that it will work just as well.

jason-a69 commented 3 years ago

Just to confirm, this worked

python3 3d_box.py --display linux_framebuffer --width 320 --height 240 --framebuffer-device /dev/fb1