Closed kmtm closed 2 years ago
I have exactly this same issue! I've checked everything that I can think of. A single board works fine but when I try to use both board.CE0 and board.CE1 as CS lines the display using CE0 responds to both drawing commands. In the code below, the CE0 display draws "Left" and then redraws to "Right" while the display using CE1 only draws "Right".
I've been working on this for a few hours and I'm a pretty stumped.
@kmtm Did you find a solution?
I'm using today's Blinka on a Raspberry Pi 4 running bullseye and I followed the directions in this learn guide.
import digitalio
import board
import time
import busio
from PIL import Image, ImageDraw, ImageFont
from adafruit_rgb_display import ili9341
from adafruit_rgb_display import st7789 # pylint: disable=unused-import
from adafruit_rgb_display import hx8357 # pylint: disable=unused-import
from adafruit_rgb_display import st7735 # pylint: disable=unused-import
from adafruit_rgb_display import ssd1351 # pylint: disable=unused-import
from adafruit_rgb_display import ssd1331 # pylint: disable=unused-import
BORDER = 20
FONTSIZE = 24
left_cs_pin = digitalio.DigitalInOut(board.CE0)
right_cs_pin = digitalio.DigitalInOut(board.CE1)
dc_pin = digitalio.DigitalInOut(board.D25)
reset_pin = digitalio.DigitalInOut(board.D24)
BAUDRATE = 24000000
spi = board.SPI()
left_disp = ili9341.ILI9341(
spi,
rotation=0,
cs=left_cs_pin,
dc=dc_pin,
#rst=reset_pin,
baudrate=BAUDRATE,
)
right_disp = ili9341.ILI9341(
spi,
rotation=0,
cs=right_cs_pin,
dc=dc_pin,
#rst=reset_pin,
baudrate=BAUDRATE,
)
if left_disp.rotation % 180 == 90:
height = left_disp.width
width = left_disp.height
else:
width = left_disp.width
height = left_disp.height
left_image = Image.new("RGB", (width, height))
left_draw = ImageDraw.Draw(left_image)
left_text = "Left"
right_image = Image.new("RGB", (width, height))
right_draw = ImageDraw.Draw(right_image)
right_text = "Right"
font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", FONTSIZE)
text_color = 128
while True:
right_draw.rectangle((0, 0, width, height), fill=(0,0,0))
(font_width, font_height) = font.getsize(right_text)
right_draw.text(
(width // 2 - font_width // 2, height // 2 - font_height // 2),
right_text,
font=font,
fill=(text_color, 255 - text_color, 255 - text_color),
)
right_disp.image(right_image)
left_draw.rectangle((0, 0, width, height), fill=(0,0,0))
(font_width, font_height) = font.getsize(left_text)
left_draw.text(
(width // 2 - font_width // 2, height // 2 - font_height // 2),
left_text,
font=font,
fill=(text_color, 255 - text_color, 255 - text_color),
)
left_disp.image(left_image)
text_color = (text_color + 10) % 255
time.sleep(0.5)
It may be that Linux is messing with the Chip Enable lines. We have instruction on how to reassign them here: https://learn.adafruit.com/circuitpython-on-raspberrypi-linux/spi-sensors-devices#reassigning-the-spi-chip-enable-lines-3097985-4.
Hi, @makermelissa! Thank you for the suggestion.
I reassigned CE0 and CE1 to GPIO 5 and 6 using the method in the learning guide that you linked. It did change the CS lines over to those pins but sadly they behave the same as when it was using the original CE0 and CE1 pins.
Ok, it was worth a shot.
So, I found a work-around by using both SPI0 and SPI1 on the RPi 4. They're separate SPI peripherals so it takes more wires and won't work for devices that don't have two SPI peripherals but it'll get the job done for my immediate use case.
Just in case anyone else needs this, to turn on SPI0 and SPI1 go to /boot/config.txt
and make sure that dtparam=spi-on
and dtoverlay=spi1-3cs
are set. (you'll need to reboot after changing them)
Then hook each display up to the various SPI0 and SPI1 pin with completely separate wiring (no shared MOSI, MISO, DC, etc) and program them separately by using busio.SPI()
and busio.SPI(board.SCK_1, MISO=board.MISO_1, MOSI=board.MOSI_1)
Hey, y'all! Glad this thread is useful a few months later :) I tried so many different things that didn't work (all the standard suggestions) and then finally hacked something new that worked.
Essentially, I actually ended up modifying a non-adafruit driver and manually threading the way the pixel data was being sent to two screens so they behave simultaneously. No need for more wiring on two separate SPIs (or, in my case, a lag between each eye when pushing new data serially)! My little robot eyes are now fully individually controllable in parallel.
If you give me a couple of days I can clean up my code and throw it up on git. Might need a little poke of a reminder as it's a busy week!
On Mon, Nov 15, 2021 at 7:37 PM Trevor Flowers @.***> wrote:
So, I found a work-around by using both SPI0 and SPI1 on the RPi 4. They're separate SPI peripherals so it takes more wires and won't work for devices that don't have two SPI peripherals but it'll get the job done for my immediate use case.
Just in case anyone else needs this, to turn on SPI0 and SPI1 go to /boot/config.txt and make sure that dtparam=spi-on and dtoverlay=spi1-3cs are set. (you'll need to reboot after changing them)
Then hook each display up to the various SPI0 and SPI1 pin with completely separate wiring (no shared MOSI, MISO, DC, etc) and program them separately by using busio.SPI() and busio.SPI(board.SCK_1, MISO=board.MISO_1, MOSI=board.MOSI_1)
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/adafruit/Adafruit_CircuitPython_RGB_Display/issues/95#issuecomment-969519975, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACK76ICZHPEXGKF22FTR32DUMGRWDANCNFSM5AL6SGHQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.
Hey, what about four screens? We need to make them work, but rpi has only two SPI interfaces. Is there any fix for CS pins behaviour?
I was able to get 2 displays working at the same time. First of all, please don't use CE0 and CE1. The reassignment of pins was only if you absolutely needed to use those because the hardware couldn't easily be reconfigured.
Additionally, this would easily let you use more than 2 displays.
In my test, I used D5 and D6 as the chip select lines and D24 as the DC line. Here's the code I used:
import time
import random
import busio
import digitalio
import board
from adafruit_rgb_display.rgb import color565
from adafruit_rgb_display import ili9341
# Configuratoin for CS and DC pins (these are FeatherWing defaults on M0/M4):
cs_pin = digitalio.DigitalInOut(board.D5)
cs2_pin = digitalio.DigitalInOut(board.D6)
dc_pin = digitalio.DigitalInOut(board.D24)
# Config for display baudrate (default max is 24mhz):
BAUDRATE = 24000000
# Setup SPI bus using hardware SPI:
spi = busio.SPI(clock=board.SCK, MOSI=board.MOSI, MISO=board.MISO)
# Create the ILI9341 display:
display = ili9341.ILI9341(spi, cs=cs_pin, dc=dc_pin, baudrate=BAUDRATE)
display2 = ili9341.ILI9341(spi, cs=cs2_pin, dc=dc_pin, baudrate=BAUDRATE)
# Fill the screen red, green, blue, then black:
for color in ((255, 0, 0), (0, 255, 0), (0, 0, 255)):
display.fill(color565(color))
display2.fill(color565(color))
# Clear the display
display.fill(0)
# Draw a red pixel in the center.
display.pixel(display.width // 2, display.height // 2, color565(255, 0, 0))
# Pause 2 seconds.
time.sleep(2)
# Clear the screen a random color
display.fill(
color565(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
)
display2.fill(
color565(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
)
I'm closing this because no modifications to the library were necessary to get this working.
Thank you for looking into this, @makermelissa! It'll be useful for future projects.
Hi @makermelissa ! Your code doesn't work for my ST7789 screens. I can draw on one or another but not on both at the same time (specifically, after I create another ST7789 object, previous one stops working).
Here is my code adapted from your example
import time
import busio
import digitalio
import board
from adafruit_rgb_display.rgb import color565
from adafruit_rgb_display.st7789 import ST7789
# Configuratoin for CS and DC pins (these are FeatherWing defaults on M0/M4):
cs_pin = digitalio.DigitalInOut(board.GP10)
cs2_pin = digitalio.DigitalInOut(board.GP11)
dc_pin = digitalio.DigitalInOut(board.GP12)
rs_pin = digitalio.DigitalInOut(board.GP13)
# Config for display baudrate (default max is 24mhz):
BAUDRATE = 24000000
# Setup SPI bus using hardware SPI:
spi = busio.SPI(clock=board.GP14, MOSI=board.GP15)
# Create the ILI9341 display:
display = ST7789(spi, rotation=0, width=240, height=240, x_offset=0, y_offset=80, baudrate=BAUDRATE,
cs=cs_pin,
dc=dc_pin,
rst=rs_pin)
display2 = ST7789(spi, rotation=0, width=240, height=240, x_offset=0, y_offset=80, baudrate=BAUDRATE,
cs=cs2_pin,
dc=dc_pin,
rst=rs_pin)
# Fill the screen red, green, blue, then black:
for color in ((255, 0, 0), (0, 255, 0), (0, 0, 255)):
display.fill(color565(color))
display2.fill(color565(color))
# Clear the display
display.fill(0)
# Draw a red pixel in the center.
display.pixel(display.width // 2, display.height // 2, color565(255, 0, 0))
# Pause 2 seconds.
time.sleep(2)
# Clear the screen a random color
display.fill(
color565(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
)
display2.fill(
color565(random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
)
Moreover, If I put the following lines instead:
display2 = ST7789(...)
display2.fill(color565(255, 0, 0))
time.sleep(2)
display1 = initDisplay(...)
display1.fill(color565(0, 255, 0))
Then the behaviour is to display red (actually, yellow. I think its because both CS are enabled by default until I initialized driver?), then wait for 2 sec, they put the first screen to black and then display green on the second screen. I would expect both screen to work at the same time?
@BioRyajenka please create a new issue referencing this issue. Thanks.
Hi @makermelissa , done (link). I also fixed a bunch of grammar and code errors in this new issue compared to my last message here :) So I hope it will make more sense now
Thank you. :)
Hi, I'm trying to control two 2.2 TFT screens, both on SPI 0 using the two chip selects (CE0 and CE1).
Whenever I display to the first screen on CE0, it's fine (i.e. only displays on the first screen), but displaying to the second screen (CE1) pushes the same image to both screens. I can't seem to figure out why. Trying to manually throw CE0 high hasn't appeared to work.
Here's the implementation (adjusted from the sample code):
Essentially the blue box appears on both screens instead of just the second one!
I'm not sure if I'm doing something wrong with the chip selects/setup, or if this library just can't support multiple SPI devices.