Git Product home page Git Product logo

adafruit_blinka_displayio's Introduction

Introduction

Documentation Status Discord Build Status Code Style: Black

displayio for Blinka

Dependencies

This driver depends on:

Installing from PyPI

On supported GNU/Linux systems like the Raspberry Pi, you can install the driver locally from PyPI. To install for current user:

pip3 install adafruit-blinka-displayio

To install system-wide (this may be required in some cases):

sudo pip3 install adafruit-blinka-displayio

To install in a virtual environment in your current project:

mkdir project-name && cd project-name
python3 -m venv .env
source .env/bin/activate
pip3 install adafruit-blinka-displayio

Contributing

Contributions are welcome! Please read our Code of Conduct before contributing to help this project stay welcoming.

Documentation

For information on building library documentation, please check out this guide.

adafruit_blinka_displayio's People

Contributors

bablokb avatar caternuson avatar dhalbert avatar foamyguy avatar janvolck avatar kattni avatar ladyada avatar lesamouraipourpre avatar makermelissa avatar mcauser avatar s-ol avatar tannewt avatar tekktrik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

adafruit_blinka_displayio's Issues

TypeError concatenating data_as_command

A Discord user mentioned in the #help-with-circuitpython room having an error raised by this line:

DISPLAY_COMMAND, CHIP_SELECT_TOGGLE_EVERY_BYTE, bytes([command] + data)

https://discord.com/channels/327254708534116352/537365702651150357/924312428844556338

I tested this with Pi 3 B+ and a ili9341 TFT display, I did not get the same error, but looking in the code I'm guessing my display doesn't use data_as_command when sending.

I was able to recreate the same error by aproximating what the displayio code is doing on that line:

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.
>>> data = b'\x00\x00\x00\xef'
>>> command = 43
>>> bytes([command] + data)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "bytes") to list
>>> 

I am looking into a fix for this.

Finish ColorConverter

ColorConverter is partially implemented and will be a big part of ePaper Displays. See #3. This likely could be reworked to make use of Pillow for dithering.

Destination must be non-negative

I modified the label simple-test again just a bit, removing the x and y positions.

import board
import terminalio
import displayio
from adafruit_display_text import label
import adafruit_ili9341

# Release any resources currently in use for the displays
displayio.release_displays()

spi = board.SPI()
tft_cs = board.CE0
tft_dc = board.D25

display_bus = displayio.FourWire(
    spi, command=tft_dc, chip_select=tft_cs, reset=board.D24
)
display = adafruit_ili9341.ILI9341(display_bus, width=320, height=240)

text = "Hello world"
text_area = label.Label(terminalio.FONT, text=text)
display.show(text_area)
print("showing")
while True:
    pass

Now I am getting this error when the code runs:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.7/threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "/home/pi/.local/lib/python3.7/site-packages/displayio/display.py", line 252, in _refresh_loop
    self.refresh()
  File "/home/pi/.local/lib/python3.7/site-packages/displayio/display.py", line 239, in refresh
    self._current_group._fill_area(buffer)  # pylint: disable=protected-access
  File "/home/pi/.local/lib/python3.7/site-packages/displayio/group.py", line 160, in _fill_area
    layer._fill_area(buffer)  # pylint: disable=protected-access
  File "/home/pi/.local/lib/python3.7/site-packages/displayio/tilegrid.py", line 279, in _fill_area
    buffer.alpha_composite(image, (int(x), int(y)))
  File "/home/pi/.local/lib/python3.7/site-packages/PIL/Image.py", line 1523, in alpha_composite
    raise ValueError("Destination must be non-negative")
ValueError: Destination must be non-negative

I think this is due to displayio label y origin being in the center. My guess is that PIL is expecting origin (0,0) top left when it draws and somewhere there is logic to convert from one to the other, but in this case it results in trying to place the label at a negative position which is throwing this error.

First thought I had to fix it was clamp the positions to 0 and positive values by using max() I can give that a try later today and make a PR if I get it working.

Blinka_Displayio has become more strict about supported devices

This issue stems from the forum post here: https://forums.adafruit.com/viewtopic.php?f=60&t=180765&p=879483

With version 0.5.9 and earlier versions of Blinka_Displayio the examples and other scripts made to work with the Blinka_Displayio_PyGameDisplay library that I created could be run on generic PCs (or pretty much any device that can run CPython and PyGame I believe).

On the newer versions 0.6.0 and 0.6.1 of Blinka_Displayio this now raises an exception when it runs on device not specifically known to be supported by Adafruit_Blinka

Traceback (most recent call last):
  File "/blinka_displayio_tests/forum_issue.py", line 1, in <module>
    import displayio
  File "/blinka_displayio_tests/test_venv/lib/python3.8/site-packages/displayio/__init__.py", line 26, in <module>
    from displayio.i2cdisplay import I2CDisplay
  File "/blinka_displayio_tests/test_venv/lib/python3.8/site-packages/displayio/i2cdisplay.py", line 30, in <module>
    import microcontroller
  File "/blinka_displayio_tests/test_venv/lib/python3.8/site-packages/microcontroller/__init__.py", line 120, in <module>
    raise NotImplementedError("Microcontroller not supported:", chip_id)
NotImplementedError: ('Microcontroller not supported:', 'GENERIC_X86')

I plan to look into this further and work on a PR to hopefully resolve this so that newer versions will be able to run these scripts successfully once again. This issue is mostly to document what is known so far in one place to reference when looking into a solution.

Add FontProtocol class to fontio library

The fontio library for CircuitPython utilizes the FontProtocol class for typing. Since this class is not present in this library, Sphinx documentation is failing to build whenever there are references to this class.

Running Sphinx v4.5.0
loading intersphinx inventory from https://docs.python.org/3/objects.inv...
loading intersphinx inventory from https://docs.circuitpython.org/en/latest/objects.inv...
building [mo]: targets for 0 po files that are out of date
building [html]: targets for 3 source files that are out of date
updating environment: [new config] 3 added, 0 changed, 0 removed
WARNING: GENERIC_X86 is not fully supported. Some features may not work.                                                                                
reading sources... [100%] index                                                                                                                         

Warning, treated as error:
autodoc: failed to import module 'scrolling_label' from module 'adafruit_display_text'; the following exception was raised:
Traceback (most recent call last):
  File "/home/grizz/.local/lib/python3.8/site-packages/sphinx/ext/autodoc/importer.py", line 62, in import_module
    return importlib.import_module(modname)
  File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 848, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/home/grizz/Projects/Adafruit_CircuitPython_Display_Text/adafruit_display_text/scrolling_label.py", line 39, in <module>
    class ScrollingLabel(bitmap_label.Label):
  File "/home/grizz/Projects/Adafruit_CircuitPython_Display_Text/adafruit_display_text/scrolling_label.py", line 56, in ScrollingLabel
    font: FontProtocol,
NameError: name 'FontProtocol' is not defined

Add Terminalio support

It would be awesome to be able to display the REPL on the display like with circuitpython. I believe we can just tap into stdout, but it may be more involved than that.

Changing the scale of a TileGrid's parent can cause a crash

Changing the scale of the parent of a TileGrid after it has been added to the parent causes a crash.

The following test file demonstrates
test_change_scale_on_a_tilegrid_parent.py

And produces

python .\test_change_scale_on_a_tilegrid_parent.py
pygame 2.0.1 (SDL 2.0.14, Python 3.8.5)
Hello from the pygame community. https://www.pygame.org/contribute.html
Traceback (most recent call last):
  File ".\test_change_scale_on_a_tilegrid_parent.py", line 38, in <module>
    display.refresh()
  File ".\lib\site-packages\blinka_displayio_pygamedisplay.py", line 113, in refresh
    self._current_group._fill_area(
  File ".\lib\site-packages\displayio\group.py", line 162, in _fill_area
    layer._fill_area(buffer)  # pylint: disable=protected-access
  File ".\lib\site-packages\displayio\tilegrid.py", line 271, in _fill_area
    image = image.resize(
  File ".\lib\site-packages\PIL\Image.py", line 1913, in resize
    im = im.resize(size, resample, box)
  File ".\lib\site-packages\PIL\Image.py", line 1935, in resize
    return self._new(self.im.resize(size, resample, box))
TypeError: integer argument expected, got float

The cause is PIL expecting integers to be passed in from tilegrid.py:line 271

Type inconcsistency in FourWire.send / _send

As far as I can tell FourWires send method expects command to be an int:

    def send(
        self, command, data: _typing.ReadableBuffer, *, toggle_every_byte: bool = False
    ) -> None:
[...]
        if not 0 <= command <= 255:
            raise ValueError("Command must be an int between 0 and 255")

and it uses command to call _send:

        self._send(DISPLAY_COMMAND, chip_select, command)

however no int is expected there:

    def _send(self, data_type: int, chip_select: int, data: _typing.ReadableBuffer):

and at least in my tests, using the FourWire class did not work as I would have expected. For my usecase I found that patching the FourWire send method and replacing the _send call with

        self._send(DISPLAY_COMMAND, chip_select, bytes([command]))

worked. Is this a bug?
Also as I came across while trying to use an e-ink display: It took me some time to find out that the EPaperDisplay class is not functional. Maybe you could replace the pass statements in not implemented methods with a raise NotImplementedError?

Publish release with latest changes to fix adafruit examples

It seems that any adafruit display example I've tried did not work on a Raspberry Pi. I would always get a: RuntimeError: Group full error when using more then 3 characters.

After debugging for a while (read way too long) I figured out this would never work (probably because of the max_size changes) with the latest pypi published version of adafruit-blinka-displayio, after I pulled this repo and used this version,everything (all the adafruit examples from this repo, guides, etc.) works like a charm.

Implement Dirty Rectangle Tracking

This library currently doesn't utilize dirty rectangle tracking, though it has partial implementation. This will speed things up a lot.

ST7735R not working with PICO_U2IF (Raspberry PICO board)

When using the ST7735R display on the Mini TFT featherwing with PICO_U2IF on a Raspberry PICO I get error:-

Exception in thread Thread-1:
Traceback (most recent call last):
File "I:\Python\lib\threading.py", line 954, in _bootstrap_inner
self.run()
File "I:\Python\lib\threading.py", line 892, in run
self._target(*self._args, **self._kwargs)
File "I:\Python\lib\site-packages\displayio\display.py", line 248, in _refresh_loop
self.refresh()
File "I:\Python\lib\site-packages\displayio\display.py", line 244, in refresh
self._refresh_display_area(area)
File "I:\Python\lib\site-packages\displayio\display.py", line 288, in _refresh_display_area
self._write(self._write_ram_command, pixels)
File "I:\Python\lib\site-packages\displayio\display.py", line 204, in _write
self._bus.send(False, data)
File "I:\Python\lib\site-packages\displayio\fourwire.py", line 116, in send
self._spi.write(data)
File "I:\Python\lib\site-packages\busio.py", line 341, in write
return self._spi.write(buf, start, end)
File "I:\Python\lib\site-packages\adafruit_blinka\microcontroller\pico_u2if\spi.py", line 49, in write
pico_u2if.spi_write(buf, start=start, end=end)
File "I:\Python\lib\site-packages\adafruit_blinka\microcontroller\pico_u2if\pico_u2if.py", line 325, in spi_write
bytes([write_cmd, chunk]) + buffer[start : (start + chunk)], True
TypeError: can't concat list to bytes

Seems to be similar to adafruit/Adafruit_Blinka#454 and changing displayio.display.py as intimated by @caternuson reply for that issue appears to fix it

pixels = list(
           numpy.dstack(((color >> 8) & 0xFF, color & 0xFF)).flatten().tolist()
       )

to

pixels = bytes(
           numpy.dstack(((color >> 8) & 0xFF, color & 0xFF)).flatten().tolist()
       )

Add support for Pillow as (virtual) display

I would like to work on supporting Pillow as a sort of virtual display. There are two reasons:

  1. I often work without real hardware, only with my laptop when I'm out of the office. I think the time-consuming layout work could be easily done with Pillow (I could also simulate different display sizes)
  2. Screenshots. Taking photos of real displays usually results in tearing

Pillow has a show() and a save() method, but no way to "refresh the display", so it will be of limited use but maybe there is a workaround for that.

My first idea was to create some special display-bus and display-driver for Pillow, but when I looked at the code of _displayio.py, the complete buffer is already a Pillow-Image, so I wonder if there is a simpler way of doing this.

Any suggestions, hints and tips are welcome, thanks!

Broken links in README

I was manually checking README contents with checklinks and it found a problem in this repo.

## adafruit/Adafruit_Blinka_Displayio


Processing      https://github.com/adafruit/Adafruit_Blinka_Displayio


List of broken links and other issues:
https://learn.adafruit.com/creating-and-sharing-a-blinka-library/sharing-our-docs-on-readthedocs
  Line: 1183
  Code: 404 Not Found
 To do: The link is broken. Double-check that you have not made any typo,
        or mistake in copy-pasting. If the link points to a resource that
        no longer exists, you may want to remove or fix the link.

Much slower pitft touchscreen performance when using displayio

Using stmpe610 resistive touchscreen chip with blinka is very fast until the point when the hx8357 screen is initialised using displayio.

I realise they both use SPI but touchscreen responsiveness is dramatically slower compared with using the pitft as a primary display for raspberry pi.

Comparison can be seen by removing hash on line 18 of the code below:

import busio
import board
import displayio
import digitalio
from adafruit_stmpe610 import Adafruit_STMPE610_SPI
import adafruit_hx8357

displayio.release_displays()
spi = board.SPI()
tft_cs = board.CE0
tft_dc = board.D25

spi = board.SPI()
cs = digitalio.DigitalInOut(board.CE1)
st = Adafruit_STMPE610_SPI(spi, cs)

display_bus = displayio.FourWire(spi, command=tft_dc, chip_select=tft_cs)
#display = adafruit_hx8357.HX8357(display_bus, width=480, height=320, backlight_pin=board.D18)

while True:
    if not st.buffer_empty:
        print(st.read_data())

Thanks

Incorrect behavior with SSD1327 via I2C

I'm not sure if this would be better reported here or on https://github.com/adafruit/Adafruit_CircuitPython_SSD1327.

When I try to use the SSD1327 via Blinka displayio, the behavior is strange. I'm using the Adafruit version of the chip: https://www.adafruit.com/product/4741, connected to an FT232H. The python environment is in Windows.

The display is 128x128, but the way it maps the grid onto the display is not correct.
As best I can tell, the display is acting as though it is only half the width it actually is, despite passing width=128, height=128.

The pixel range y = 0, x=[0:64] is written to the area y=0, x=[0:128]. The pixel range y=0, x=[64:128] is written to y=1, x=[0:64]. This results in twice as many output lines as intended, so the display will write y=[0:64] and then rewrite the whole display with y=[64:128].

The below example, adapted from the various example code, attempts to write a block of 128x64 white to the display, which should cover the top half in white. What actually happens is it fills the whole display, then wipes it back out.

import board
import displayio
import adafruit_ssd1327

displayio.release_displays()

# Use for I2C
i2c = board.I2C()
display_bus = displayio.I2CDisplay(i2c, device_address=0x3D)


WIDTH = 128
HEIGHT = 128
BORDER = 0
FONTSCALE = 1

display = adafruit_ssd1327.SSD1327(display_bus, width=HEIGHT, height=HEIGHT)

# Make the display context
splash = displayio.Group()
display.auto_refresh = False
display.show(splash)

# Draw a background rectangle, but not the full display size
color_bitmap = displayio.Bitmap(
    #display.width - BORDER * 2, display.height - BORDER * 2, 1
    128, 64, 1
)


color_palette = displayio.Palette(1)
color_palette[0] = 0xFFFFFF  # White
bg_sprite = displayio.TileGrid(
    color_bitmap, pixel_shader=color_palette, x=BORDER, y=BORDER
)
splash.append(bg_sprite)
display.refresh()


displayio.release_displays()

Finish Shapes Supoort

Shapes is currently only extending bitmaps which was enough for the DisplayShapes library to work, but it isn't complete.

[WIP] Rewrite of Blinka DisplayIO from CircuitPython core

Work in Progress :: Rewrite of Adafruit_Blinka_Displayio from CircuitPython core

Repository/Branch: https://github.com/lesamouraipourpre/Adafruit_Blinka_Displayio/tree/display-core

Inception

This work started with the intent of translating display_core.c from CircuitPython core to Blinka to be used as the superclass of Display and EPaperDisplay. Without realising it, it quickly escalated into doing a full re-translation of core displayio to Blinka.

Goals

  • Phase 1
    • Expose the same API as is exposed from core displayio in CircuitPython 7. Done, only partially tested
    • If the API in Blinka is not the same as the API in CircuitPython core, the API in the core takes precedence. Do not care about breaking changes in Blinka DisplayIO. Done
    • To translate vectorio as part of displayio. Done, only partially tested
    • To translate bitmaptools as part of displayio. Done, not tested
  • Phase 2 Testing. Testing. And lots more testing.
  • Phase 3 Decide how best to speed up the code, by further translating some of it to use numpy and maybe PIL/Pillow

Open issues on Blinka DisplayIO

Testing

ST7735R (Color SPI) - Working correctly

0.96" SPI Colour LCD (160x80) from Pimoroni. (Driver ST7735S - using Adafruit_CircuitPython_ST7735R library)

SH1107 (B&W I2C) - Working correctly

1.12" Mono OLED (128x128, white/black) Breakout โ€“ I2C from Pimoroni. (Driver SH1107 - using Adafruit_CircuitPython_DisplayIO_SH1107)

SSD1608 / SSD1680 (eInk SPI) - Not working, not sure why

Inky pHAT Black&White - (SSD1608)
Inky pHAT Yellow/Black/White - (Documented as SSD1608 which is only a B&W eInk controller, I'm assuming it is a SSD1680)

WHAT NOW?

If you have any hardware running Blinka and an available display to test with, please test the branch below and report:
https://github.com/lesamouraipourpre/Adafruit_Blinka_Displayio/tree/display-core

Please report any successes or failures as an issue on my repository NOT on adafruit/Adafruit_Blinka_Displayio
https://github.com/lesamouraipourpre/Adafruit_Blinka_Displayio/issues
Note: It is Pure Python, so it WILL BE SLOW. Conversion of parts to NumPy (or alternative) will follow if testing is successful.

I'll try to update the Wiki on my repo as progress is made:
https://github.com/lesamouraipourpre/Adafruit_Blinka_Displayio/wiki

Scaling group does not effect image

It seems that scaling Groups that are holding images from adafruit_imageload does not cause the image to get scaled bigger.

Sample script like this:

import board
import displayio
import terminalio
import adafruit_ili9341
import adafruit_imageload

# Release any resources currently in use for the displays
displayio.release_displays()

spi = board.SPI()
tft_cs = board.CE0
tft_dc = board.D25

display_bus = displayio.FourWire(
    spi, command=tft_dc, chip_select=tft_cs, reset=board.D24
)
display = adafruit_ili9341.ILI9341(display_bus, width=320, height=240, rotation=180)
display.brightness = 0

bitmap, palette = adafruit_imageload.load("4bit.bmp",
                                         bitmap=displayio.Bitmap,
                                         palette=displayio.Palette)

tile_grid = displayio.TileGrid(bitmap, pixel_shader=palette)

group = displayio.Group(scale=10)  # same result as scale=1
group.append(tile_grid)
display.show(group)
while True:
    pass

Running a similar script on PyPortal scales the image up.

Add OnDiskBitmap support

This one should be pretty easy. Open a bitmap with Pillow, and return in Displayio Bitmap format.

OverflowError: Python int too large to convert to C long

I got this error while running the electioncal guide code. It took about 5 minutes for it to appear, so it wasn't immediate. It's possibly a Pillow bug. I need to look into it more.

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.7/threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "/home/pi/.local/lib/python3.7/site-packages/displayio/display.py", line 244, in _refresh_loop
    self.refresh()
  File "/home/pi/.local/lib/python3.7/site-packages/displayio/display.py", line 231, in refresh
    self._current_group._fill_area(buffer)  # pylint: disable=protected-access
  File "/home/pi/.local/lib/python3.7/site-packages/displayio/group.py", line 160, in _fill_area
    layer._fill_area(buffer)  # pylint: disable=protected-access
  File "/home/pi/.local/lib/python3.7/site-packages/displayio/group.py", line 160, in _fill_area
    layer._fill_area(buffer)  # pylint: disable=protected-access
  File "/home/pi/.local/lib/python3.7/site-packages/displayio/group.py", line 160, in _fill_area
    layer._fill_area(buffer)  # pylint: disable=protected-access
  [Previous line repeated 1 more time]
  File "/home/pi/.local/lib/python3.7/site-packages/displayio/tilegrid.py", line 289, in _fill_area
    image, (round(x), round(y)), source=(round(source_x), round(source_y))
  File "/home/pi/.local/lib/python3.7/site-packages/PIL/Image.py", line 1541, in alpha_composite
    background = self.crop(box)
  File "/home/pi/.local/lib/python3.7/site-packages/PIL/Image.py", line 1134, in crop
    return self._new(self._crop(self.im, box))
  File "/home/pi/.local/lib/python3.7/site-packages/PIL/Image.py", line 1154, in _crop
    return im.crop((x0, y0, x1, y1))
OverflowError: Python int too large to convert to C long

SSD1306 displays not working properly

I have a 128x64 display using SSD1306, and it's not working properly.
I noticed that 16384 bytes of data is sent every time, while only 1024 bytes (128 x 64 / 8, 1 bit per pixel) should be sent.
I've read some other issues and I understand that this is a known issue. Creating this issue to help others find it.
Can we add some text to the README file to notify future users that monochrome displays are not supported properly yet?

SSD1305: "bytearray index out of range"

Hi,

I'm having trouble with setting up a SSD1305 OLED display using a raspberry pi.

I'm trying to run the example code as shown in adafruit/Adafruit_CircuitPython_DisplayIO_SSD1305.

However this leads to the following error message:

%Run example.py
Traceback (most recent call last):
  File "/home/pi/oled-micropython/example.py", line 25, in <module>
    display = adafruit_displayio_ssd1305.SSD1305(display_bus, width=WIDTH, height=HEIGHT)
  File "/home/pi/.local/lib/python3.9/site-packages/adafruit_displayio_ssd1305.py", line 80, in __init__
    super().__init__(
  File "/usr/local/lib/python3.9/dist-packages/displayio/display.py", line 122, in __init__
    self._initialize(init_sequence)
  File "/usr/local/lib/python3.9/dist-packages/displayio/display.py", line 154, in _initialize
    data_size = init_sequence[i + 1]
IndexError: bytearray index out of range

Does anyone have any suggestions? :)

SSD1327: raspberry pi display corruption

This is the result of attempting to run the "simpletest" example through i2c on a raspberry pi zero 2 and raspberry pi 4. Have tried both displays, for the same results on each. Any suggestions? Seems like a driver bug.

IMG_7238_HEIC

Setting scale has unusual behaviour

Setting scale (greater than 1) when creating the root Group added to the Display has unusual scaling behaviour.

import displayio
from adafruit_display_shapes.circle import Circle
from adafruit_display_shapes.rect import Rect
from blinka_displayio_pygamedisplay import PyGameDisplay
# import board
import time

INITIAL_SCALE = 2  # Change this

splash = displayio.Group(max_size=20, scale=INITIAL_SCALE)

display = PyGameDisplay(width=800, height=600)
# display = board.DISPLAY
display.show(splash)

# Make a background color fill
color_bitmap = displayio.Bitmap(display.width, display.height, 1)
color_palette = displayio.Palette(1)
color_palette[0] = 0xFFFFFF
bg_sprite = displayio.TileGrid(color_bitmap, x=0, y=0, pixel_shader=color_palette)
splash.append(bg_sprite)

while True:
    for scale in (1,2):
        splash.scale = scale
        print(f"scale={scale}")

        center_x = display.width // 2
        center_y = display.height // 2
        for i in range(5):
            size = 20 * (i + 1)
            size2 = size * 2
            circle = Circle(center_x ,center_y, size, outline=0xFF00FF)
            splash.append(circle)
            rect = Rect(center_x - size, center_y - size, size2, size2, outline=0x00FFFF)
            splash.append(rect)

        time.sleep(2)
        while len(splash)>1:
            splash.pop()

while display.running:
    pass

INITIAL_SCALE = 1
Initial_Scale_1
INITIAL_SCALE = 2
Initial_Scale_2

This behaviour doesn't happen on PyPortal so it seems to be an issue with the Blinka implementation.

I'm intending to look into this further, time permitting.

Changes in PR #61 has broken Adafruit_CircuitPython_Display_Text with Blinka

Ref: PR #61

Changes that were made for the above PR have broken another part of DisplayIO, Adafruit_CircuitPython_Display_Text, when used with Blinka.

import displayio
import terminalio
from adafruit_display_text import label
from blinka_displayio_pygamedisplay import PyGameDisplay

display = PyGameDisplay(width=320, height=240)
splash = displayio.Group(max_size=10)
display.show(splash)

lbl = label.Label(font=terminalio.FONT, text="Hello World", x=20, y=20)
splash.append(lbl)

while display.running:
    pass

Crashes with:

python test.py 
pygame 2.0.1 (SDL 2.0.14, Python 3.9.5)
Hello from the pygame community. https://www.pygame.org/contribute.html
Traceback (most recent call last):
  File "/home/~~~/Adafruit_Blinka_Displayio/dist/test.py", line 18, in <module>
    lbl = label.Label(font=terminalio.FONT, text="Hello World", x=20, y=20)
  File "/home/~~~/Adafruit_CircuitPython_Display_Text/adafruit_display_text/label.py", line 79, in __init__
    super().__init__(font, **kwargs)
  File "/home/~~~/Adafruit_CircuitPython_Display_Text/adafruit_display_text/__init__.py", line 221, in __init__
    super().__init__(max_size=1, x=x, y=y, scale=1, **kwargs)
  File "/home/~~~/Adafruit_Blinka_Displayio/displayio/group.py", line 52, in __init__
    self.scale = scale  # Set the scale via the setter
  File "/home/~~~/Adafruit_CircuitPython_Display_Text/adafruit_display_text/__init__.py", line 363, in scale
    self.local_group.scale = new_scale
AttributeError: 'Label' object has no attribute 'local_group'

The high-level cause is Python's not being an object-oriented language but only a scripting language with pseudo object-oriented capabilities. Specifically, it doesn't initialise the object properties at object creation time but only when they are first assigned.

I'm working on a fix within Blinka_Displayio. If I can't figure one out, I have a working fix on Adafruit_CircuitPython_Display_Text but I would sooner keep the fix within Blinka.

GC9A01 display issue on Raspberry Pi 3 - no text is displayed

Hello,
So, I bought one of GC9A01 chip based SPI displays off AliExpress (not a link to AliExpress), and I started testing it. I use CircuitPython with latest adafruit-blinka installed on my Raspberry Pi 3B.
So, I installed all necessary libraries:

I'm using following code:

import time
import board
import math
import busio
import terminalio
import displayio
from adafruit_display_text import label
import gc9a01

# Release any resources currently in use for the displays
displayio.release_displays()

spi = board.SPI()

# Make the displayio SPI bus and the GC9A01 display
display_bus = displayio.FourWire(spi, command=board.D25, chip_select=board.D18, reset=board.D27)
display = gc9a01.GC9A01(display_bus, width=240, height=240)

# Make the main display context
main = displayio.Group()
display.show(main)

# Draw a text label
text = "Hello\nWorld!"
text_area = label.Label(terminalio.FONT, text=text, color=0xFFFF00,
                        anchor_point=(0.5,0.5), anchored_position=(0,0))
text_group = displayio.Group(scale=2)
text_group.append(text_area) 
main.append(text_group)

# Animate the text 
theta = math.pi
r = 75
while True:
    print(time.monotonic(),"hello")
    text_group.x = 120 + int(r * math.sin(theta))
    text_group.y = 120 + int(r * math.cos(theta))
    theta -= 0.05
    time.sleep(0.01)

The problem is, that this code gives me following output (sorry my hands are shaking):

20220320_150302.mp4

So, I decided to use Pi Pico to test if display is faulty. So I flashed it with latest CircuitPython firmware, installed everything, modified my code to Pico's pins, and here is the result:

20220320_183037.mp4

I really don't think it's the CircuitPython GC9A01's fault. I also checked wiring on my Raspberry Pi 3 like a million times. So, my guess is that it's blinka-displayio's fault, as Pico uses CircuitPython's displayio, meanwhile Pi 3 uses blinka-displayio, which is a port to Unix & Unix-like operating systems.

I'm also not using integrated (hardware) Chip-Select pin, as it's not recommended.

Let me know what you think is the issue.
Awaiting your response and thank you for everything upfront ๐Ÿ™


Code source

Remove thread enabling/disabling for autorefresh

I discovered this when working on the Blinka PyPortal library that threads don't like to be started and stopped a bunch, so rather than stopping the thread when turning off autorefresh, it should just make it so the thread "pauses" by not doing anything.

Occasional crashes when updating while drawing

For more information see https://forums.adafruit.com/viewtopic.php?f=60&t=168440

It appears that there is some kind of race condition caused by multithreading. The error is:

Exception in thread Thread-1:
Traceback (most recent call last):
File "/home/pi/.local/lib/python3.8/threading.py", line 932, in _bootstrap_inner
self.run()
File "/home/pi/.local/lib/python3.8/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "/home/pi/.local/lib/python3.8/site-packages/displayio/display.py", line 248, in _refresh_loop
self.refresh()
File "/home/pi/.local/lib/python3.8/site-packages/displayio/display.py", line 235, in refresh
self._current_group._fill_area(buffer) # pylint: disable=protected-access
File "/home/pi/.local/lib/python3.8/site-packages/displayio/group.py", line 160, in _fill_area
layer._fill_area(buffer) # pylint: disable=protected-access
File "/home/pi/.local/lib/python3.8/site-packages/displayio/group.py", line 160, in _fill_area
layer._fill_area(buffer) # pylint: disable=protected-access
File "/home/pi/.local/lib/python3.8/site-packages/displayio/group.py", line 160, in _fill_area
layer._fill_area(buffer) # pylint: disable=protected-access
File "/home/pi/.local/lib/python3.8/site-packages/displayio/tilegrid.py", line 269, in _fill_area
if self._absolute_transform.mirror_x:
AttributeError: 'NoneType' object has no attribute 'mirror_x'

As the poster mentioned, None is checked before this, so I can only assume that it changed between the check for None and the check of the variable. Likely, I will probably need to copy the class variable to a local variable first and use that so it can change at will without affecting this.

Add SH1107 display support

There is a parameter missing on the Blinka version of displayio.Display specifically SH1107_addressing.

Traceback (most recent call last):
  File "roomtemp.py", line 41, in configure_display
    display = adafruit_displayio_sh1107.SH1107(display_bus, width=128, height=128)
  File "lib/python3.7/site-packages/adafruit_displayio_sh1107.py", line 73, in __init__
    SH1107_addressing=True,
TypeError: __init__() got an unexpected keyword argument 'SH1107_addressing'

The parameter appears to have been renamed from column_and_page_addressing in adafruit/circuitpython@06a3d15 which was added in adafruit/circuitpython@f21dc25

This renders the Adafruit_CircuitPython_DisplayIO_SH1107 library unusable with Blinka.

My test hardware is the Pimoroni 1.12" Mono OLED (128x128, white/black) Breakout - I2C on a Raspberry Pi.

PS. I might try to work on a PR, but I don't fully understand the linkage between the C code in adafruit/circuitpython and the Python code in Blinka.

Extra scaling on some Groups

I am still working on trying to distill this issue down further to figure out the root cause, but I wanted to get down what I've discovered so far.

I first noticed this issue in the context of display_text labels (and bitmap_labels) so the current example code uses those, but I hope to narrow it down further to just Group, Tilegrid, and Bitmap.

Code:

import displayio
from adafruit_display_text import label
from adafruit_bitmap_font import bitmap_font

# Make the display context
display = # Specific Display setup

splash = displayio.Group(max_size=10)
display.show(splash)
font = bitmap_font.load_font("Helvetica-Bold-16.bdf")

control_text = label.Label(font, text="Hello World!", color=0xFFFF00)
control_text.x = 10
control_text.y = 20

text_group = displayio.Group(max_size=10, scale=2)
group_scaled_text = label.Label(font, text="Hello World!", color=0xFFFF00)
text_group.x = 10
text_group.y = 50
text_group.append(group_scaled_text)

self_scaled_text = label.Label(font, text="Hello World!", color=0xFFFF00, scale=2)
self_scaled_text.x = 10
self_scaled_text.y = 100

splash.append(text_group)
splash.append(control_text)
splash.append(self_scaled_text)
while True:
    pass

With this code I think we would expect one small label (the control) and two labels that are 2x the size of the control. One is scaled via it's own scale property, the other is scaled with another Group. I don't think there should be any visible difference between the latter two.

On a PyPortal that is exactly what we get (excuse the blurry photo):
image

With Blinka_Displayio the label that is scaled using it's own init parameter seems to be getting scaled an extra time so when scale=2 it looks visually on the screen like it would if it were actually scale=4

image

Clean up duplicate code

Pylint is failing because there's a little duplicate code here and there. That should probably be cleaned up rather than just ignored.

Float int TypeError from label simpletest

I have this label simpletest modified slightly to work with Blinka and my screen.

import board
import terminalio
from adafruit_display_text import label
import adafruit_ili9341

# Release any resources currently in use for the displays
displayio.release_displays()

spi = board.SPI()
tft_cs = board.CE0
tft_dc = board.D25

display_bus = displayio.FourWire(
    spi, command=tft_dc, chip_select=tft_cs, reset=board.D24
)
display = adafruit_ili9341.ILI9341(display_bus, width=320, height=240)

text = "Hello world"
text_area = label.Label(terminalio.FONT, text=text)
text_area.x = 10
text_area.y = 10
display.show(text_area)
print("showing")
while True:
    pass

When I try to run it I'm getting this error from inside of Blinka displayio:

pi@raspberrypi:~/display_layouts $ python3 examples/label_test.py
showing
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python3.7/threading.py", line 917, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.7/threading.py", line 865, in run
    self._target(*self._args, **self._kwargs)
  File "/home/pi/.local/lib/python3.7/site-packages/displayio/display.py", line 252, in _refresh_loop
    self.refresh()
  File "/home/pi/.local/lib/python3.7/site-packages/displayio/display.py", line 239, in refresh
    self._current_group._fill_area(buffer)  # pylint: disable=protected-access
  File "/home/pi/.local/lib/python3.7/site-packages/displayio/group.py", line 160, in _fill_area
    layer._fill_area(buffer)  # pylint: disable=protected-access
  File "/home/pi/.local/lib/python3.7/site-packages/displayio/tilegrid.py", line 272, in _fill_area
    buffer.alpha_composite(image, (x, y))
  File "/home/pi/.local/lib/python3.7/site-packages/PIL/Image.py", line 1544, in alpha_composite
    self.paste(result, box)
  File "/home/pi/.local/lib/python3.7/site-packages/PIL/Image.py", line 1496, in paste
    self.im.paste(im, box)
TypeError: integer argument expected, got float

Not working with HX8357

Initialization appears to be fine. It will draw fine if I set the display with to 320. It doesn't like it when I set the display to a width of 480. It won't draw at all. Setting it to a width of 400 causes a diagonal line to appear, so the issue is likely in the code that draws to the display itself, but possibly in the tilegrid drawing function.
IMG_2062

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.