pimoroni / pimoroni-pico

Libraries and examples to support Pimoroni Pico add-ons in C++ and MicroPython.
https://shop.pimoroni.com/collections/pico
MIT License
1.33k stars 499 forks source link

Graphic glitch introduced by v0.0.7 #89

Closed slabua closed 2 years ago

slabua commented 3 years ago

I think either by this commit or this commit some graphic glitch has been introduced regarding the pico display since moving from release v0.0.6 to v0.0.7. The glitch is visible in this video. It works flawlessly when using v.0.0.6. Any ideas as to why?

Gadgetoid commented 3 years ago

That looks very much like some random memory region is walking over the display buffer, and I think you're right to point the finger at https://github.com/pimoroni/pimoroni-pico/commit/85906b105947b6fe6c69e8d899015510ddd99232

This is probably also the cause of #86 - it seems that the C bindings and Python itself are not respecting each others boundaries.

slabua commented 3 years ago

Yes, and if there's no clearing of the screen, the glitch spans periodically as in the video, but clearing up the screen kind of reset its y position not letting it span vertically, somehow. hmm..

agoodney commented 3 years ago

FWIW I've been chasing some weird behavior (crashes, hangs) that seem an awful lot like Python and C not respecting each others boundaries. It seems to trigger when writing near the end of the display buffer. I've been trying to come up with a minimal proof-of-bug, but that's been difficult because it depends on which Python variables are declared etc. Making the display buffer width x height x 4 fixes the problem though. If I get a nice, simple and reliably bad test-case, I'll post it.

callimero commented 3 years ago

Yea did see that also. Mine was only at the last few lines, so I declared 10 lines more for the buffer :)

Gadgetoid commented 3 years ago

I finally witnessed this for myself when working on #107. This has all the hallmarks of the stack creeping up over a display buffer allocated at the bottom of the heap, but for some reason isn't as incredibly crashy as I would expect.

Re-running an example from Thonny by pressing only the "Play" button - presumably re-starting the script without a reset - will break it pretty quickly, though. I have to manually reset my Pico more often than not.

This is - as you say @agoodney - really difficult to reliably replicate. A lot of the problem might be due to memory fragmentation - since nobody expects to have to write MicroPython as defensively as they write C for a small micro - and can be mitigated by tiptoeing around the problem.

Take this code for example:

import gc
import micropython
gc.collect()

test = [x for x in range(8*1024)]
micropython.mem_info()
print(len(test))

test = test[10:]
micropython.mem_info()
print(len(test))

gc.collect()
micropython.mem_info()

On CPython you wouldn't bat an eyelid. Sure, dropping some items from the front of a list to create a circular buffer might be a little blunt, but it would work.

On MicroPython, though, we see a - relatively - huge chunk of our RAM allocated right after test = test[10:] because this creates a copy, and removes the reference to the previous list:

# Initial memory
stack: 508 out of 7936
GC: total: 192064, used: 37520, free: 154544
 No. of 1-blocks: 36, 2-blocks: 10, max blk sz: 2048, max free sz: 5050
8192

# Memory after `test = test[10:]`
stack: 508 out of 7936
GC: total: 192064, used: 70288, free: 121776
 No. of 1-blocks: 38, 2-blocks: 10, max blk sz: 2048, max free sz: 3245
8182

# Memory after `gc.collect()`
stack: 508 out of 7936
GC: total: 192064, used: 37456, free: 154608
 No. of 1-blocks: 34, 2-blocks: 10, max blk sz: 2046, max free sz: 3245

So the defensive approach in this case might be to use:

for x in range(10):
    test.pop(0)

This might seem jarring and unpythonic... but it uses 16 bytes of memory instead of 32k!

These are extreme, synthetic examples but these temporary memory allocations- even when they are garbage collected- do not come at zero cost. The resulting memory fragmentation will eventually result in no single, large enough, contiguous block of memory existing for a given allocation and then everything falls apart.

Normally this wouldn't be such a big deal, the Pico and most popular MicroPython boards have plenty of RAM... but then we're eating 64k just for the display buffer.

I've waffled a bit here and I'm unsure if memory fragmentation is actually exacerbating or causing this, but I think it's along the same lines.

Gadgetoid commented 3 years ago

I tried using uploading the uf2 file from https://github.com/pimoroni/pimoroni-pico/releases/tag/v0.0.6 since you're talking about a glitch introduced in v0.0.7 but it makes no difference

It sounds like your issues are related to MicroPython/Thonny - though it could conceivably be a slightly fried Pico I haven't exactly been careful with mine, and haven't seen anywhere near the level of bonkers you describe.

That said I've had some weird out-of-memory errors which appear to have been related to my distros (old) version of Thonny quietly smashing code onto the Pico via the REPL. Updating to 3.3.6 (https://github.com/thonny/thonny/releases) seems to have fixed this and gave me an inkling that "MicroPython Generic" is not compatible with the Pico:

WARNING: Could not sync device's clock: can't import name RTC
WARNING: Could not validate time: can't import name RTC

These suggest Thonny was trying to run code on the Pico to sync the clock and switching to use "MicroPython (Rasberry Pi Pico)", which appears not to do this, has helped.

Gadgetoid commented 3 years ago

The following code- at least for me- reliably replicates a region of memory being drawn over the screen. They appear to share the same region of memory, but micropython.mem_info claims they do not.

import machine
import picodisplay as display
import time
import random
import micropython

overflow = 4800 # 240 * 10 * 2 (extra 10 rows)

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

# Create a bytearray for the display buffer
display_buffer = bytearray(width * height * 2)

# Before overlap allocation
# micropython.mem_info(1)

# Why does data written here appear on the display!?
overlap = bytearray(overflow)

# After overlap allocaton
# micropython.mem_info(1)

display.init(display_buffer)
display.set_backlight(1.0)

n = 0
while True:
    # Fill the "overlay" byearray with random noise
    # This will appear at the bottom of the screen!?!?
    # micropython.mem_info shows these buffers *do not* overlap in memory
    overlap[random.randint(0, overflow-1)] = random.randint(0, 255)

    # Verify the display is actually 135 tall
    display.set_pen(0, 0, 255)
    display.rectangle(0, 0, 10, 10)

    # Draw *something* to the display
    display.set_pen(0, 255, 0)
    display.rectangle(0, 40, 240, 30)
    display.set_pen(255, 0, 0)
    display.text( "test {}".format(n), 1, 40, 240, 4 )

    # Verify the display is actually 135 tall
    display.set_pen(0, 0, 255)
    display.rectangle(0, 125, 10, 10)

    display.update()
    n += 1

If I inspect display_buffer for contents immediately after drawing, the data is usually found at a rather extreme offset:

import picodisplay as display

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

display_buffer = bytearray(width * height * 2)
display.init(display_buffer)

# Draw something in the display
display.set_pen(255, 255, 255)
display.rectangle(0, 0, 10, 10)

# Find it in the buffer
for x in range(len(display_buffer)):
    if display_buffer[x] > 0:
        print(x, display_buffer[x-10:x+10])
        print("Data found at offset: {}".format(x))
        break

This suggests that C++ and MicroPython don't even agree about which region of memory the display buffer is in, much less respect any boundaries. From the perspective of both languages they are operating normally, but C++ is "seeing" the buffer as being offset.

MicroPython ca3d51f on 2021-03-31; Raspberry Pi Pico with RP2040
Type "help()" for more information.
>>> %Run -c $EDITOR_CONTENT
3200 bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff')
Data found at offset: 3200

This is why enlarging the buffer, or allocating a dummy empty bytearray after it works since it gives a buffer zone for that disagreement.

agoodney commented 3 years ago

FWIW the example code from Gadetoid does not appear to cause corruption on my Pico. I'm running Thonny 3.3.4 and my Pico version string is "MicroPython v1.14-113-g73fce1cd6-dirty".

Repo found here: https://github.com/agoodney/micropython

This is micropython + the Pimoroni CI patches to get the modules to build. I wanted the FAT fs for an SD card.

agoodney commented 3 years ago

I can confirm that after being freshly powered on, the example from Gadgetoid does not show corruption.

However, if you run the temperature.py demo first, then 'stop' in Thonny, then Gadgetoid's example will show corruption.

Hitting ctrl-d to soft-reboot the Pico does not fix the issue.

Yay! This feels like progress.

veryalien commented 3 years ago

I accidentally reproduced this problem with pimoroni-pico-micropython v0.1.1 and the pico explorer balls_demo.py With v0.0.6 I can get up to 500 Balls going slowly around the explorer display. With v0.1.1 I got the error: ‘int’ object has no attribute ‘x’ It is definitely corrupting memory, in this case the balls object list.

When I change the code to allocate 3 bytes per pixel for the display:

display_buffer = bytearray(width height 3) # 2-bytes per pixel (RGB565)

the problem goes away, however I can only allocate 100 Balls before it runs out of memory because of the huge display_buffer.

I reported the same issue on the Pimoroni forum, mostly just for devilment.

This looks like a fundemental object memory management problem which needs to be fixed asap, otherwise you can't trust any program which dynamically allocates objects to behave as expected.

tonygo commented 3 years ago

I reported these problems on the Pimoroni Forum on 23 Feb. I've had all the strange messages and corrupted bottom edge of the display since that time. https://forums.pimoroni.com/t/large-programs-on-pico-explorer-display-problem/16401 But nobody followed it up. I'm very glad someone else is pushing for a fix.

Gadgetoid commented 3 years ago

This looks like a fundemental object memory management problem which needs to be fixed asap, otherwise you can't trust any program which dynamically allocates objects to behave as expected.

It smells like this to me, too, but since we're doing "Kinda Weird Things" with the MicroPython firmware by baking in our own C libraries I'm not confident enough that we haven't borked something up ourselves to point the finger upstream.

Replicating this weirdness in pure MicroPython would certainly help narrow things down.

This sort of deep-routed memory weirdness problem really blows my understanding of C/C++/Embedded C/MicroPython thoroughly out of the water and I'm somewhat at a loss here.

veryalien commented 3 years ago

Just to annoy everybody, I can't reproduce the same problem any more! v0.1.1 is now working just fine with the explorer balls_demo.py and 500 Balls without any problems at all! All I did (I think) was swap v0.0.6 alpha and V0.1.1 a couple of times on the same pico I've been using, messed with balls_demo.py and then put it back to the original code and then I noticed it had started working "all on its own". I didn't nuke the internal file system between v0.1.1 and v0.0.06 and I do have a few explorer demo scripts stored there. How do you erase the entire pico flash memory to clean it all up? Is there an erase uf2 which I should be using? Now I'm suspecting Thonny again (I don't know why) and/or other subtle problems in the internal micropython file system for trying to run half-overwritten code. Possibly? Maybe? Clutching at straws. Seriously, I give up....

dsssssssss9 commented 3 years ago

Below is a link to the uf2 file which erases the contents of the flash on the Pico..

I hope this helps

https://www.raspberrypi.org/documentation/rp2040/getting-started/static/6f6f31460c258138bd33cc96ddd76b91/flash_nuke.uf2

slabua commented 3 years ago

Any progress on this issue?

tonygo commented 3 years ago

I'm still having the same problem. sm - Random pixels-1

I ran a copy of the workout script: Raspberry Pi Pico & Pico Explorer Workout : 15 Steps - Instructables Followed by this, updated to Explorer and extended, font program from Les Wright

'''
Fonts for the pico display!
Les Wright 2021
V 1.1
Update with a suggestion from Steve Borg:
https://forums.pimoroni.com/t/pico-display-and-fonts/16194/18

"Refactor it slightly so that the various functions take an optional parameter to tell it
whether to do a display.update() you can get it so it draws much more quickly.
That way those that like the teleprompter type output can leave it to update after each character
and those that don’t could update after each string."

printchar naw has the extra parameter: Charupdate (Boolean (True/False)
printchar(letter,xpos,ypos,size,charupdate)
delchar has the same
delchar(xpos,ypos,size,delupdate)

Printstring has two extra args charupdate and strupdate (Boolean (True/False)
printstring(string,xpos,ypos,size,charupdate,strupdate)  
These say whether to call display.update()on individual chars (slow) or on the entire string (fast)
You can set them both to false if you want, send multiple lines, then do a display.upadte() manually if you like
(see example code below)

'''
import math

import picoexplorer as display
# Initialise display with a bytearray display buffer
buf = bytearray(display.get_width() * display.get_height() * 2)
display.init(buf)

# sets up a handy function we can call to clear the screen
def clear():
    display.set_pen(0,0,0)
    display.clear()
    display.update()

clear()

def ring2(cx,cy,r):   # Centre (x,y), radius
    for angle in range(0, 90, 2):  # 0 to 90 degrees in 2s
        y3=int(r*math.sin(math.radians(angle)))
        x3=int(r*math.cos(math.radians(angle)))
        display.pixel(cx-x3,cy+y3)  # 4 quadrants
        display.pixel(cx-x3,cy-y3)
        display.pixel(cx+x3,cy+y3)
        display.pixel(cx+x3,cy-y3)

#ASCII Character Set
cmap = ['00000000000000000000000000000000000', #Space
        '00100001000010000100001000000000100', #!
        '01010010100000000000000000000000000', #"
        '01010010101101100000110110101001010', ##
        '00100011111000001110000011111000100', #$
        '11001110010001000100010001001110011', #%
        '01000101001010001000101011001001101', #&
        '10000100001000000000000000000000000', #'
        '00100010001000010000100000100000100', #(
        '00100000100000100001000010001000100', #)
        '00000001001010101110101010010000000', #*
        '00000001000010011111001000010000000', #+
        '000000000000000000000000000000110000100010000', #,
        '00000000000000011111000000000000000', #-
        '00000000000000000000000001100011000', #.
        '00001000010001000100010001000010000', #/
        '01110100011000110101100011000101110', #0
        '00100011000010000100001000010001110', #1
        '01110100010000101110100001000011111', #2
        '01110100010000101110000011000101110', #3
        '00010001100101011111000100001000010', #4
        '11111100001111000001000011000101110', #5
        '01110100001000011110100011000101110', #6
        '11111000010001000100010001000010000', #7
        '01110100011000101110100011000101110', #8
        '01110100011000101111000010000101110', #9
        '00000011000110000000011000110000000', #:
        '01100011000000001100011000010001000', #;
        '00010001000100010000010000010000010', #<
        '00000000001111100000111110000000000', #=
        '01000001000001000001000100010001000', #>
        '01100100100001000100001000000000100', #?
        '01110100010000101101101011010101110', #@
        '00100010101000110001111111000110001', #A
        '11110010010100111110010010100111110', #B
        '01110100011000010000100001000101110', #C
        '11110010010100101001010010100111110', #D
        '11111100001000011100100001000011111', #E
        '11111100001000011100100001000010000', #F
        '01110100011000010111100011000101110', #G
        '10001100011000111111100011000110001', #H
        '01110001000010000100001000010001110', #I
        '00111000100001000010000101001001100', #J
        '10001100101010011000101001001010001', #K
        '10000100001000010000100001000011111', #L
        '10001110111010110101100011000110001', #M
        '10001110011010110011100011000110001', #N
        '01110100011000110001100011000101110', #O
        '11110100011000111110100001000010000', #P
        '01110100011000110001101011001001101', #Q
        '11110100011000111110101001001010001', #R
        '01110100011000001110000011000101110', #S
        '11111001000010000100001000010000100', #T
        '10001100011000110001100011000101110', #U
        '10001100011000101010010100010000100', #V
        '10001100011000110101101011101110001', #W
        '10001100010101000100010101000110001', #X
        '10001100010101000100001000010000100', #Y
        '11111000010001000100010001000011111', #Z
        '01110010000100001000010000100001110', #[
        '10000100000100000100000100000100001', #\
        '00111000010000100001000010000100111', #]
        '00100010101000100000000000000000000', #^
        '00000000000000000000000000000011111', #_
        '11000110001000001000000000000000000', #`
        '00000000000111000001011111000101110', #a
        '10000100001011011001100011100110110', #b
        '00000000000011101000010000100000111', #c
        '00001000010110110011100011001101101', #d
        '00000000000111010001111111000001110', #e
        '00110010010100011110010000100001000', #f
        '000000000001110100011000110001011110000101110', #g
        '10000100001011011001100011000110001', #h
        '00100000000110000100001000010001110', #i
        '0001000000001100001000010000101001001100', #j
        '10000100001001010100110001010010010', #k
        '01100001000010000100001000010001110', #l
        '00000000001101010101101011010110101', #m
        '00000000001011011001100011000110001', #n
        '00000000000111010001100011000101110', #o
        '000000000001110100011000110001111101000010000', #p
        '000000000001110100011000110001011110000100001', #q
        '00000000001011011001100001000010000', #r
        '00000000000111110000011100000111110', #s
        '00100001000111100100001000010000111', #t
        '00000000001000110001100011001101101', #u
        '00000000001000110001100010101000100', #v
        '00000000001000110001101011010101010', #w
        '00000000001000101010001000101010001', #x
        '000000000010001100011000110001011110000101110', #y
        '00000000001111100010001000100011111', #z
        '00010001000010001000001000010000010', #{
        '00100001000010000000001000010000100', #|
        '01000001000010000010001000010001000', #}
        '01000101010001000000000000000000000' #}~
]

def printchar(letter,xpos,ypos,size,charupdate):
    origin = xpos
    charval = ord(letter)
    #print(charval)
    index = charval-32 #start code, 32 or space
    #print(index)
    character = cmap[index] #this is our char...
    rows = [character[i:i+5] for i in range(0,len(character),5)]
    #print(rows)
    for row in rows:
        #print(row)
        for bit in row:
            #print(bit)
            if bit == '1':
                display.pixel(xpos,ypos)
                if size==2:
                    display.pixel(xpos,ypos+1)
                    display.pixel(xpos+1,ypos)
                    display.pixel(xpos+1,ypos+1)
            xpos+=size
        xpos=origin
        ypos+=size
    if charupdate == True:
        display.update()

def delchar(xpos,ypos,size,delupdate):
    if size == 1:
        charwidth = 5
        charheight = 9
    if size == 2:
        charwidth = 10
        charheight = 18
    display.set_pen(0,0,0)
    display.rectangle(xpos,ypos,charwidth,charheight) #xywh
    if delupdate == True:
        display.update()

def printstring(string,xpos,ypos,size,charupdate,strupdate):
    if size == 2:
        spacing = 14
    else:
        spacing = 8
    for i in string:
        printchar(i,xpos,ypos,size,charupdate)
        xpos+=spacing
    if strupdate == True:
        display.update()

#display one char at a time, like an old serial term...
test1 = "Hello World!!"
display.set_pen(255,0,0)
printstring(test1,0,0,2,True,False)

#display string fast
test2 = "Les Wright 2021"
display.set_pen(0,255,0)
printstring(test2,0,20,2,False,True)

#display one char at a time, like an old serial term...
test3 = 'abcdefghijk'
display.set_pen(0,0,255)
printstring(test3,0,60,2,True,False)

#display one char at a time, like an old serial term...
test4 = 'lmnopqrstuvwxyz'
display.set_pen(0,0,255)
printstring(test4,0,80,2,True,False)

#display one char at a time, like an old serial term...
test5 = 'ABCDEFGHIJKLM'
display.set_pen(0,0,255)
printstring(test5,0,100,2,True,False)

#display one char at a time, like an old serial term...
test6 = 'NOPQRSTUVWXYZ'
display.set_pen(0,0,255)
printstring(test6,0,120,2,True,False)

#display blocks of text fast
test7 = '`~!@#$%^&*()_-+=['
printstring(test7,0,140,2,False,False)
test8 = ']\\{}|;\':"<>?,./'
printstring(test8,0,160,2,False,False)
display.update()

display.set_pen(255,255,0)
ring2(20,220,20)
display.update()

spinner = '-\|/-\|/'
for i in range(50):
    for x in spinner:
        display.set_pen(255,255,0)
        printchar(x,220,20,2,True)
        delchar(220,20,2,True)

I also lost communication between Thonny and the Pico several times. (Unplug, plug in, click on STOP) So, this is still a major problem with large scripts.

helgibbons commented 3 years ago

I think I just ran into this issue with Pimoroni Pico LiPo and Explorer Base - my code fails reliably with v0.2.3 after 14 iterations, with:

Traceback (most recent call last):
  File "<stdin>", line 39, in <module>
TypeError: unsupported types for __mul__: 'float', ''

It seems to work OK if I increase the display buffer to * 3.

Code:

# This example shows how to read the voltage from a LiPo battery connected to Pimoroni Pico LiPo, and uses this reading to calculate how much charge is left in the battery. 
# It then displays the info on the screen of Pico Display or Pico Explorer.
# With Pimoroni Pico LiPo, you can read the battery percentage while it's charging!
# Remember to save this code as main.py on your Pico if you want it to run automatically.

from machine import ADC, Pin
import utime
import picoexplorer as display      # change "picodisplay" to "picoexplorer" if you're using a Pico Explorer

# Set up and initialise display
buf = bytearray(display.get_width() * display.get_height() * 2)
display.init(buf)
#display.set_backlight(0.8)         # comment out this line if you have a Pico Explorer as it doesn't have a controllable backlight

vsys = ADC(29)                      # reads the system input voltage
charging = Pin(24, Pin.IN)          # reading GP24 tells us whether or not USB power is connected
conversion_factor = 3 * 3.3 / 65535

full_battery = 4.2                  # these are our reference voltages for a full/empty battery, in volts
empty_battery = 2.8                 # the values could vary by battery size/manufacturer so you might need to adjust them

while True:
    voltage = vsys.read_u16() * conversion_factor
    percentage = 100 * ((voltage - empty_battery) / (full_battery - empty_battery))
    if percentage > 100:
        percentage = 100

    # draws the battery
    display.set_pen(0, 0, 0)
    display.clear()
    display.set_pen(190, 190, 190)
    display.rectangle(0, 0, 220, 135)
    display.rectangle(220, 40, 20, 55)
    display.set_pen(0, 0, 0)
    display.rectangle(3, 3, 214, 129)
    display.set_pen(0, 255, 0)

    # draws a green box for the battery level
    display.rectangle(5, 5, int((210 / 100) * percentage), 125)

    # adding text
    display.set_pen(255, 0, 0)
    if charging.value() == 1:         # if it's plugged into USB power...
        display.text("Charging!", 15, 90, 240, 4)

    display.text('{:.2f}'.format(voltage) + "v", 15, 10, 240, 5)
    display.text('{:.0f}%'.format(percentage), 15, 50, 240, 5)

    # low battery alarm (Pico Explorer only, you'll need to have GP0 and AUDIO connected with a jumper wire)
    display.set_audio_pin(0)
    if percentage < 5:              # if the battery is less than 5%
        display.set_tone(262)         # then make an annoying noise
    display.update()
    utime.sleep(0.5)
tonygo commented 3 years ago

I'm still having the same problem with the Pimoroni UF2. I've think I've found a solution with a pure Micropython ST7789 library. See my post and code here: https://forums.pimoroni.com/t/pico-explorer-screen-corruption-and-communication-crashes/18173 I hope a few people will give it a try.

agoodney commented 3 years ago

I ended up getting the following working quite easily.

https://github.com/peterhinch/micropython-nano-gui

tonygo commented 3 years ago

Thank you. That looks really comprehensive. I will give it a try. Just wish the Pimoroni UF2 could be fixed so newbies are not put off.

Gadgetoid commented 3 years ago

Just wish the Pimoroni UF2 could be fixed so newbies are not put off.

You and me both. 😭😭😭😭

bogbean commented 2 years ago

I'm a newbie and this issue has definitely put me off.

I get the same screen corruption and memory problems. Judging from the time this issue has been around it seems Pimoroni aren't going to do anything about it.

I'm planning to try the Micropython ST7789 library solution suggested by tonygo.

tonygo commented 2 years ago

Have fun, please let others know how you get on.

Gadgetoid commented 2 years ago

It took some fresh eyes on this problem to finally see what was happening and - hopefully - fix it. See: https://github.com/pimoroni/pimoroni-pico/pull/250

Thank you @ZodiusInfuser 🥇 - despite this staring me in the face, and being so close I couldn't see the wood for the trees.

For anyone wanting to try this fix, you can grab the MicroPython build from CI, here:

https://github.com/pimoroni/pimoroni-pico/suites/5297692052/artifacts/164346006

I know this whole thing has been a drawn out travesty. Thank you for providing test cases and sorry for taking so long and for this being a bit of a showstopper for displays.

If anyone's still hanging on we'd appreciate some feedback!

tonygo commented 2 years ago

This link appears to be broken - 404 error:

https://github.com/pimoroni/pimoroni-pico/suites/5297692052/artifacts/164346006

Regards

Tony Goodhew

On 15 February 2022 at 12:41 Philip Howard @.***> wrote:

It took some fresh eyes on this problem to finally see what was happening and - hopefully - fix it. See: #250 https://github.com/pimoroni/pimoroni-pico/pull/250

Thank you @ZodiusInfuser https://github.com/ZodiusInfuser 🥇 - despite this staring me in the face, and being so close I couldn't see the wood for the trees.

For anyone wanting to try this fix, you can grab the MicroPython build from CI, here:

https://github.com/pimoroni/pimoroni-pico/suites/5297692052/artifacts/164346006

I know this whole thing has been a drawn out travesty. Thank you for providing test cases and sorry for taking so long and for this being a bit of a showstopper for displays.

If anyone's still hanging on we'd appreciate some feedback!

—
Reply to this email directly, view it on GitHub https://github.com/pimoroni/pimoroni-pico/issues/89#issuecomment-1040226377 , or unsubscribe https://github.com/notifications/unsubscribe-auth/AA3K7VOLTORV3MVN45QWPCLU3JCWVANCNFSM4Y2V4Z6Q .
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 .
You are receiving this because you commented.Message ID: ***@***.***>
helgibbons commented 2 years ago

The link is working OK for me - I think you might need to be logged in to Github to be able to download artifacts?

tonygo commented 2 years ago

Thanks

Gadgetoid commented 2 years ago

Thanks @helgibbons I keep forgetting that fact :facepalm:

tonygo commented 2 years ago

Sorry Phil, I've still got a problem. See here: https://forums.pimoroni.com/t/pico-explorer-screen-corruption-and-communication-crashes/18173

ZodiusInfuser commented 2 years ago

@tonygo That was my mistake. PicoExplorer uses a different code section than the two PicoDisplays so did not have the fix applied. I have now run your test case and fixed the glitch. Could you test this build to confirm? https://github.com/pimoroni/pimoroni-pico/suites/5400141396/artifacts/170277436

tonygo commented 2 years ago

@Zodiusinfuser Thank you very much. That works properly with these test scripts on my set up.

Gadgetoid commented 2 years ago

Fixes merged and released in - https://github.com/pimoroni/pimoroni-pico/releases/tag/1.18.2

Hopefully that's everything!

Thank you all involved, and sorry it took us so darned long!

tonygo commented 2 years ago

So happy we now have it fixed and available to all. Perhaps a note on the shop description to ensure users update their UF2?

Gadgetoid commented 2 years ago

Perhaps a note on the shop description to ensure users update their UF2?

Probably a good idea, @helgibbons?

helgibbons commented 2 years ago

Aye aye - I've added notes to Display Pack, Display Pack 2.0 and Pico Explorer👍

tonygo commented 2 years ago

Thanks

Tony

On 01 March 2022 at 12:08 Hel Gibbons @.***> wrote:

Aye aye - I've added notes to Display Pack, Display Pack 2.0 and Pico Explorer 👍

—
Reply to this email directly, view it on GitHub https://github.com/pimoroni/pimoroni-pico/issues/89#issuecomment-1055374723 , or unsubscribe https://github.com/notifications/unsubscribe-auth/AA3K7VJY4BTKQV7EQP6QZ2TU5YCDRANCNFSM4Y2V4Z6Q .
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 .
You are receiving this because you were mentioned.Message ID: ***@***.***>