Pico Display drawing bitmaps help

I’m trying to display an image on the Pico Display, using the tutorial from Penguin Tutor - display animations

I start out by getting the width and height of the display, initializing a display_buffer as a bytearray( width * height * 2 ). I’ve created my raw 565 byte converted image. The program will read the raw file into the display_buffer. But when the display is updated the image shows only the bottom half on the top half of the display, and left side is on the right side of the screen, with the right edge of the image is in the middle of the display. And the bottom half of the display shows random noise.

I’ve also noticed when trying to set the all the bytes in the display_buffer to give a full display red color, the display only shows the red up to where noise starts showing as in the above image.

So I did some tests to see where the bytes within display_buffer are set. I cleared the display to all black using display.set_pen(0,0,0), then display.clear(). I then set the pen to full red display.set_pen(255,0,0) followed by display.setPixel(0,0). The Pico Display would show the top left pixel as red. So I then decided to check each byte within display_buffer array for any non-zero values, to print out the byte location and it’s value. I would suspect that display_buffer[0] would have a value, but the first index to show a non-zero value was display_buffer[41201] with 248.

I would have assumed that the bytes in display_buffer would align with the pixels in the Pico Display.

Can anyone explain the relation between the bytes in display_buffer and the picodisplay?

Included is my sample code for examining changes in the buffer:

import picodisplay as display

width = display.get_width()
height = display.get_height()

display_buffer = bytearray(width * height * 2) # 2-bytes per pixel (RGB565)
display.init(display_buffer)
display.set_backlight(1.0)

display.set_pen(0,0,0)
display.clear()
display.update()

display.set_pen(255,0,0)
display.pixel(0,0)
display.pixel(0,1)
display.pixel(1,0)
display.pixel(1,1)

display.update()

print (“count:%d” % len(display_buffer))

for i in range( 0, (width * height * 2)):
x = display_buffer[i]
if (x != 0):
print( “i:%d %d” % (i,x))

print( “done.”)

Any help is appreciated. Thank you.

Here is the original image I’m trying to display:
lamp_32

Tony @Tonygo2 is I think the guy to talk to. He’s the display wizard around here.

I’m currently away on holiday without any Pico bit and bobs.

Funnily enough a couple of weeks ago I tried a similar technique with a WS Display screen, (160x128pixels) and also got the random rubbish after a few lines of what I expected.

I’ll have another go when I get back home on my Pimoroni Display.

I hope anyone else giving this a try will join in the discussion.

1 Like

Thank you for responding. I hope you have a great holiday. I look forward to your findings when you get to it.

Thanks again.

Hi,
one thing I notice, is that the display buffer can’t be big enough to hold all the color values.
It is 2 bytes per pixel, whereas the color value is 3 bytes.
Therefore the display buffer can’t be organized straight forward.
That means that set_pen has() to do some form of color mapping to match 3 bytes into 2 bytes.
Also the display_pixel() can’t just put the value in the array at x/y
Perhaps the problem lies there?
Thomas

Yes, the image shown is 3bytes RGB, but was only for reference to show how the image should look. It is not the file being used on the pico display. I converted that image to a RGB565 raw byte file. The file is what is being shown on the photo of the pico display with the noise on the bottom half.

I’ve got this working correctly on a Pico Explorer with twice the size of screen. There were a few problems on the way.

I met this little fellow in Sri Lanka!

I found it difficult getting the .raw file to the Pico using my PC but managed it with rshell using a Raspberry Pi 4.

When I first ran the display program the image was offset to the left about 50% with the left hand half on the right of the screen with a few random dots at the bottom.

I re-arranged the display program into the order I normally use:

  • import libraries
  • set up screen (+clear it) and devices
  • user defined routines - lower levels first
  • main program
import picoexplorer as display
width = display.get_width()
height = display.get_height()

display_buffer = bytearray(width * height * 2)  # 2-bytes per pixel (RGB565)
display.init(display_buffer)
# Clear screen
display.set_pen(0,0,0)
display.clear()
display.update()

def blit_image_file (filename):
    # This is based on a binary image file (RGB565) with the same dimensions as the screen
    # updates the global display_buffer directly
    global display_buffer
    with open (filename, "rb") as file:
        position = 0
        while position < (width * height * 2):
            current_byte = file.read(1)
            # if eof
            if len(current_byte) == 0:
                break
            # copy to buffer
            display_buffer[position] = ord(current_byte)
            position += 1            
    file.close()
    
def setup():
    blit_image_file ("LizRAW.raw")
    display.update()
    
setup()

I then unplugged the USB from the computer and plugged it in again to re-set it.
I ran the program again and it worked perfectly.

I moved the program over to the PC and plugged in the Pico. Did a bit more editing and ran the modified script - slight off-set to the left. I unplugged and re-plugged the USB cable and ran it again with no editing.

It appears to need a newly reset Pico to work!

I hope this helps.

When I get a chance I will try to get this working on my Waveshare displays. I think they have the 2 bytes the other way round and it is easier to set each pixel to its RGB565 colour.

Please let me know how you get on.

@Tonygo2 Thank you for your response. Everything looked good as far as the code is concerned. But every time I ran the program from Thonny, the pixel noise would show on the bottom half of the screen.

The key was to call the program “main.py” and restart the Pico. The image was drawn correctly when ran as the default program. I’m curious why the image buffer gets in an improper state starting from Thonny.

I was beating my head on a wall, when the solution was just restart the pico.

Thanks again for you help.

Glad you can get it working.

There is something not quite right with the here - I suspect the way the buffer is working. You should not have to powerup/down after editing nor get random rubbish appearing on the screen.

It is a real pain putting the RAW image file onto the Pico. It would be easier to store the image data as numbers within the program. This means processing the .png file in a different way.

I don’t remember the exact situation, but I do remember being thankful I had added the Pico reset button. No having to power cycle my Pico by unplugging it. I’m pretty sure it was graphics related though?
Early days still IMHO, lots of us are still learning the ins and outs. It’s info like this that helps those of us that aren’t as knowledgeable get by though. ;)