1

I use MicroPython on my Raspberry Pi Pico and try to display a BLOB coming from an HTTP API on a Waveshare ePaper display. This is my code:

epd = EPD_7in5_B()
epd.Clear()

while(True):
    response = urequests.get('http://<<myRaspiPicoW>>/screenshotCreator/latestImage?blackAndWhite=true&asWaveshareBytes=true')
    if response.status_code == 200:
        epd.buffer_black = response.content
        epd.display()
    else:
        print('Request failed')

    epd.sleep()
    time.sleep(30)

Running this code works pretty nice, but since I want to update the display every couple of minutes, I'm running into an OutOfMemory exception for the second run:

Traceback (most recent call last):
  File "<stdin>", line 283, in <module>
  File "urequests.py", line 20, in content
MemoryError: memory allocation failed, allocating 11520 bytes

The line throwing the exception is epd.buffer_black = response.content. From what I learned about MicroPython I could imagine that response.content is somehow kept in memory after the loop run, so I played around with del response or gc.collect(), but no luck.

I also saw that urequests has the option to access the raw response content. From C# I'm familiar with stream APIs to copy bytes from one array to another. Is there a similar API for bytearray, e. g.:

i = 0
for chunk in response.iter_content(chunk_size=128):
    epd.buffer_black.write(chunk, i * 128)
    i++

So how can I work around this problem, e. g. by freeing memory or using a stream API?

3
  • 2
    You're holding a reference to the 'previous content' in epd.buffer_black while you are collecting the 'current content' - right up to the point at which the assignment to buffer_black is complete: i.e., you will have two lots of content in memory. Do you really need to have buffer_black always set? Commented Jul 3, 2023 at 17:08
  • Ah you mean I could set epd.buffer_black to None after epd.display()? Commented Jul 3, 2023 at 17:10
  • 1
    You'll have to tell me! I don't know whether the ePaper thing needs to retain its buffer_black value after the display() call returns. Worth a try, though. (Edited) Oh, I see you did. Commented Jul 3, 2023 at 22:12

1 Answer 1

1

I was able to solve it by resetting the epd.buffer_black after each iteration with an empty bytearray. This is my final code:

epd = EPD_7in5_B()
epd.Clear()
empty_buffer = bytearray(0)

while(True):
    response = urequests.get('http://<<myRaspiPicoW>>/screenshotCreator/latestImage?blackAndWhite=true&asWaveshareBytes=true')
    if response.status_code == 200:
        epd.buffer_black = response.content
        epd.display()
    else:
        print('Request failed')

    epd.sleep()
    epd.buffer_black = empty_buffer
    response = None
    time.sleep(30)

Kudos to @arfur-narf for pointing this out 💪🏻

Sign up to request clarification or add additional context in comments.

1 Comment

Might be worth setting 'response' to None at the same point.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.