🇺🇸Adafruit will not be shipping orders on Independence Day Monday 7/4/2022. Please allow extra time for your order to ship and plan accordingly.🇺🇸
0

MatrixPortal Memory Error
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Re: MatrixPortal Memory Error

by Tortilla on Mon Jan 24, 2022 6:04 pm

dastels wrote:Can you post your code again, making sure the formatting carries over? I want to try with exactly what you have on the board.

Dave


Ok, I hope this shows the formatting:

Code: Select all | TOGGLE FULL SIZE
"""One panel display using 64 X 32 RGB panel to scroll ESPN game information"""
import gc
import time
import json
from adafruit_datetime import datetime, timedelta
import board
from adafruit_matrixportal.matrixportal import MatrixPortal

Memory_free = gc.mem_free()
print("Total memory free right after importing matrixportal library is", Memory_free)
# import terminalio


USE_24HR_TIME = False
TIME_ZONE_OFFSET = -8  # hours ahead or behind Zulu time, e.g. Pacific is -8
TIME_ZONE_NAME = "PST"
# SCROLL_DELAY = 0.03

#  Create a list of dictionaries for ESPN API's
#  Note that College Baseball doesn't start until mid-February,
#  so NHL Hockey (Sport 1)is displayed for now
SPORTS = [
    {
        "name": "College Baseball",
        "url": "http://site.api.espn.com/apis/site/v2/sports/baseball/college-"
        "baseball/scoreboard",
    },
    {
        "name": "NHL Hockey",
        "url": "http://site.api.espn.com/apis/site/v2/sports/hockey/nhl/scoreboard",
    },
]
current_game = 0
current_sport = 1
sports_data = []


EVENTS_LOCATION = ["events"]
STATUS_LOCATION = ["status", "type", "description"]
BROADCAST_LOCATION = ["competitions", 0, "broadcasts"]
IS_FINAL_LOCATION = ["competitions", 0, "status", "type", "id"]
SCORES_LOCATION = ["competitions", 0, "competitors"]
SCORE_0_LOCATION = ["competitions", 0, "competitors", 0, "score"]
SCORE_1_LOCATION = ["competitions", 0, "competitors", 1, "score"]

months = [
    "Jan",
    "Feb",
    "March",
    "April",
    "May",
    "June",
    "July",
    "Aug",
    "Sept",
    "Oct",
    "Nov",
    "Dec",
]

Memory_free = gc.mem_free()
print("Total memory free right before matrixportal call is", Memory_free)

matrixportal = MatrixPortal(
    url=SPORTS[current_sport]["url"],
    status_neopixel=board.NEOPIXEL,
)


def format_date(iso_formatted_date):
    if iso_formatted_date is None:
        return "When: Unavailable"
    date = datetime.fromisoformat(iso_formatted_date[:-1])
    date += timedelta(hours=TIME_ZONE_OFFSET)

    if USE_24HR_TIME:
        timestring = "%d:%d %s" % (date.hour, date.minute, TIME_ZONE_NAME)
    elif date.hour > 12:
        timestring = "%d:%d pm %s" % (
            abs((date.hour - 12) % 12),
            date.minute,
            TIME_ZONE_NAME,
        )
    else:
        timestring = "%d:%d am %s" % (date.hour, date.minute, TIME_ZONE_NAME)
    return "%s %d, %s" % (months[date.month - 1], date.day, timestring)


def format_score(scores, is_final):
    home_score = scores[0]["score"]
    away_score = scores[1]["score"]
    if not home_score or not away_score:
        return "Unavailable"
    if int(is_final) == 3:
        return "%s - %s" % (home_score, away_score)
    return " "


def format_available(value):
    if value is None:
        return "Unavailable"
    return value


def format_broadcast(value):
    if not value:
        value = "N/A"
    else:
        value = matrixportal.network.json_traverse(value, [0, "names", 0])
    return "Airing on: " + value


def get_game_number():
    return "Game %d of %d" % (current_game + 1, len(sports_data))


def update_labels():
    # Set the labels for the current game data
    matrixportal.set_text(SPORTS[current_sport]["name"], 0, False)
    matrixportal.set_text(sports_data[current_game]["name"], 1, False)
    matrixportal.set_text(sports_data[current_game]["date"], 2, False)
    matrixportal.set_text(sports_data[current_game]["broadcast"], 3, False)
    matrixportal.set_text(sports_data[current_game]["status"], 4, False)
    matrixportal.set_text(get_game_number(), 5, False)
    matrixportal.set_text(sports_data[current_game]["score"], 6)
    # wait 2 seconds for display to complete
    time.sleep(2)


def fetch_sports_data(reset_game_number=True):
    # Fetches and parses data for all games for the current sport
    # pylint: disable=global-statement
    global sports_data, current_game, current_sport
    matrixportal.url = SPORTS[current_sport]["url"]
    sports_data.clear()
    raw_data = json.loads(matrixportal.fetch(auto_refresh=False))
    events = raw_data["events"]
    for event in events:
        game_data = {}
        game_data["name"] = format_available(event["name"])
        game_data["date"] = format_date(event["date"])
        game_data["status"] = "Game status: " + format_available(
            matrixportal.network.json_traverse(event, STATUS_LOCATION)
        )
        game_data["broadcast"] = format_broadcast(
            matrixportal.network.json_traverse(event, BROADCAST_LOCATION)
        )
        scores = matrixportal.network.json_traverse(event, SCORES_LOCATION)
        is_final = matrixportal.network.json_traverse(event, IS_FINAL_LOCATION)
        game_data["score"] = format_score(scores, is_final)
        sports_data.append(game_data)
    if reset_game_number or current_game > len(sports_data):
        current_game = 0
    update_labels()


FONT = "tom-thumb.bdf"
# FONT = terminalio.FONT

# Sports Name
matrixportal.add_text(text_font=FONT, text_position=(5, 3), is_data=False)

# Game Name
matrixportal.add_text(
    text_font=FONT,
    text_wrap=35,
    line_spacing=0.75,
    text_position=(5, 16),
    is_data=False,
)

# Date
matrixportal.add_text(text_font=FONT, text_position=(5, 10), is_data=False)

# Broadcast Information
matrixportal.add_text(text_font=FONT, text_position=(5, 20), is_data=False)

# Game Status
matrixportal.add_text(text_font=FONT, text_position=(5, 25), is_data=False)

# Game Number
matrixportal.add_text(text_font=FONT, text_position=(40, 10), is_data=False)

# Score
matrixportal.add_text(text_font=FONT, text_position=(32, 16), is_data=False)

last_update = time.monotronic()
UPDATE_DELAY = 7
fetch_sports_data()

while True:
    current_sport = 1
    if time.monotonic() > last_update + UPDATE_DELAY:
        current_game += 1
        last_update = time.monotonic()
    if current_game >= len(sports_data):
        fetch_sports_data(False)
        current_game = 0
    update_labels()
    # time.sleep(7)


I know that my code has some functional problems that I was going to be working on if I could get past the Memory Error.

Thanks again for helping with this.

Tortilla
 
Posts: 31
Joined: Sun Jan 09, 2022 5:03 am

Re: MatrixPortal Memory Error

by dastels on Mon Jan 24, 2022 6:36 pm

OK, with the code you just posted I get
Code: Select all | TOGGLE FULL SIZE
code.py output:
Total memory free right after importing matrixportal library is 32544
Total memory free right before matrixportal call is 31920
Traceback (most recent call last):
  File "code.py", line 66, in <module>
  File "adafruit_matrixportal/matrixportal.py", line 97, in __init__
  File "adafruit_matrixportal/graphics.py", line 67, in __init__
  File "adafruit_matrixportal/matrix.py", line 192, in __init__
MemoryError:

Code done running


So the MatrixPortal library take sup a BIG chunk, and your code is enough that there's not room to create the MatrixPortal object.

I'm still concerned about the lack of information about the error.

Dave

dastels
 
Posts: 10158
Joined: Tue Oct 20, 2015 3:22 pm

Re: MatrixPortal Memory Error

by dastels on Mon Jan 24, 2022 6:46 pm

OK, I changed the MatrixPortal instantiation code to:
Code: Select all | TOGGLE FULL SIZE
try:
    matrixportal = MatrixPortal(
        url=SPORTS[current_sport]["url"],
        status_neopixel=board.NEOPIXEL,
        )
except MemoryError as err:
    print(type(err))
    print(err.args)
    print(err)

and its output is
Code: Select all | TOGGLE FULL SIZE
<class 'MemoryError'>
()


So it's just a bare MemoryError with no information attached?? I've never seen that before. They're usually an allocation error with information about how much was requested. Dan?

Dave

dastels
 
Posts: 10158
Joined: Tue Oct 20, 2015 3:22 pm

Re: MatrixPortal Memory Error

by danhalbert on Mon Jan 24, 2022 6:50 pm

This means there is so little memory left that there was not even room to construct the error message. It does not happen that often. There is an "emergency buffer" but we may not be using it. Sorry that it's so uninformative.

danhalbert
 
Posts: 3257
Joined: Tue Aug 08, 2017 12:37 pm

Re: MatrixPortal Memory Error

by dastels on Mon Jan 24, 2022 7:05 pm

Options?

Switch to C++ with protomatter?

Make a build of CP with the MatrixPortal stuff frozen?

??

Dave

dastels
 
Posts: 10158
Joined: Tue Oct 20, 2015 3:22 pm

Re: MatrixPortal Memory Error

by Tortilla on Mon Jan 24, 2022 9:41 pm

dastels wrote:Options?

Switch to C++ with protomatter?

Make a build of CP with the MatrixPortal stuff frozen?

??

Dave


Well, thanks for hanging in there on this. Your output with the MemoryError now exactly matches mine.

I talked to some guys this weekend and the consensus seems to be that my code is just too large for the memory on the Matrix Portal board. I was attempting to take the ESPN game schedule code which was written for the Adafruit MagTag project and create a one-sport schedule board to display game information on an LED display, primarily for college baseball. Obviously with the MagTag, you have buttons to switch sports and scroll to the next game, etc. but I am only interested in displaying the schedule information for one sport, so I thought the Matrix Portal might work. The MagTag has 4 MByte of Flash and 2 MByte of PSRAM versus 512KB flash and 192K of SRAM for the Matrix Portal, so the Matrix Portal just doesn't have the memory.

If the Matrix Portal had more memory, it would be a fantastic display board for these kinds of projects.

Of course, if anyone has some other ideas, I would love to hear them.

Tortilla
 
Posts: 31
Joined: Sun Jan 09, 2022 5:03 am

Re: MatrixPortal Memory Error

by dastels on Mon Jan 24, 2022 10:37 pm

An ESP32-S2 (4M flash, 2M PSRAM) based MatrixPortal would be nice. Alas, there isn't one. And the Matrix Featherwing doesn't appear to have a version for the ESP32-S2 Feather. Using a Feather nRF52840 (1MB flash and 256KB SRAM) https://www.adafruit.com/product/4062 + the matching Matrix Featherwing https://www.adafruit.com/product/4702 and an Airlift Featherwing https://www.adafruit.com/product/4264 would do a good job of it (as long as the wings don't conflict).

Again, you can always switch to C++/Arduino.

Dave

dastels
 
Posts: 10158
Joined: Tue Oct 20, 2015 3:22 pm

Re: MatrixPortal Memory Error

by Tortilla on Mon Jan 24, 2022 11:08 pm

dastels wrote:An ESP32-S2 (4M flash, 2M PSRAM) based MatrixPortal would be nice. Alas, there isn't one. And the Matrix Featherwing doesn't appear to have a version for the ESP32-S2 Feather. Using a Feather nRF52840 (1MB flash and 256KB SRAM) https://www.adafruit.com/product/4062 + the matching Matrix Featherwing https://www.adafruit.com/product/4702 and an Airlift Featherwing https://www.adafruit.com/product/4264 would do a good job of it (as long as the wings don't conflict).

Again, you can always switch to C++/Arduino.

Dave


I'm definitely considering the Arduino. Thanks.

Tortilla
 
Posts: 31
Joined: Sun Jan 09, 2022 5:03 am

Re: MatrixPortal Memory Error

by MakerMelissa on Wed Jan 26, 2022 3:50 pm

This library was always on the large size and it or dependent libraries have likely grown since it was first written. As Dan mentioned, you should make sure you are using .mpy files. If you're still having issues, we may need to freeze a library into CircuitPython.

MakerMelissa
 
Posts: 296
Joined: Wed Jun 05, 2013 2:10 am

Re: MatrixPortal Memory Error

by dastels on Wed Jan 26, 2022 3:58 pm

I can confirm the error with fresh MPY files.

Dave

dastels
 
Posts: 10158
Joined: Tue Oct 20, 2015 3:22 pm

Re: MatrixPortal Memory Error

by MakerMelissa on Wed Jan 26, 2022 4:03 pm

Thank you Dave. You may also be able to remove any libraries from lib that appear in https://github.com/adafruit/circuitpyth ... ain/frozen to shave off a little of the memory used such as busdevice and esp32spi.

MakerMelissa
 
Posts: 296
Joined: Wed Jun 05, 2013 2:10 am

Re: MatrixPortal Memory Error

by dastels on Wed Jan 26, 2022 4:44 pm

I added modules to lib in response to import errors, and esp32spi was one of those.

Dave

dastels
 
Posts: 10158
Joined: Tue Oct 20, 2015 3:22 pm

Re: MatrixPortal Memory Error

by MakerMelissa on Wed Jan 26, 2022 5:58 pm

Ok, thanks. That's helpful to know.

MakerMelissa
 
Posts: 296
Joined: Wed Jun 05, 2013 2:10 am

Re: MatrixPortal Memory Error

by Tortilla on Wed Jan 26, 2022 6:23 pm

MakerMelissa wrote:This library was always on the large size and it or dependent libraries have likely grown since it was first written. As Dan mentioned, you should make sure you are using .mpy files. If you're still having issues, we may need to freeze a library into CircuitPython.


Yes, all of my library files are .mpy and they are the latest version.

Tortilla
 
Posts: 31
Joined: Sun Jan 09, 2022 5:03 am

Re: MatrixPortal Memory Error

by Tortilla on Thu Jan 27, 2022 7:27 pm

MakerMelissa wrote: If you're still having issues, we may need to freeze a library into CircuitPython.


That would be great. I would rather not give up on my project if it might still be able to work.

Tortilla
 
Posts: 31
Joined: Sun Jan 09, 2022 5:03 am

Please be positive and constructive with your questions and comments.