rm-hull / luma.led_matrix

Python module to drive LED Matrices & 7-segment displays (MAX7219) and RGB NeoPixels (WS2812 / APA102)
https://luma-led-matrix.readthedocs.io
MIT License
525 stars 157 forks source link

OSError: [Errno 24] Too many open files #190

Closed linuxminty closed 5 years ago

linuxminty commented 5 years ago

Type of Raspberry Pi

Model 1, B+ (This is a first-generation B+)

Linux Kernel version

pi@raspberrypi-B-Plus:~ $ uname -a
Linux raspberrypi-B-Plus 4.19.42+ #1219 Tue May 14 21:16:38 BST 2019 armv6l GNU/Linux

Expected behaviour

I have a ZeroSeg 7-segment add-on display on a Raspberry Pi model 1 B+ (first generation B+). I've taken the date and time code from the sevensegment_demo.py and am running it with Python 3, with the addition of "while True" and "cleanup()."

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2017-18 Richard Hull and contributors
# See LICENSE.rst for details.
"""
Example for seven segment displays.
"""
import time
from datetime import datetime

from luma.led_matrix.device import max7219
from luma.core.interface.serial import spi, noop
from luma.core.virtual import viewport, sevensegment

def date(seg):
    """
    Display current date on device.
    """
    now = datetime.now()
    seg.text = now.strftime("%m-%d-%y")

def clock(seg, seconds):
    """
    Display current time on device.
    """
    interval = 0.5
    for i in range(int(seconds / interval)):
        now = datetime.now()
        seg.text = now.strftime("%H-%M-%S")

        # calculate blinking dot
        if i % 2 == 0:
            seg.text = now.strftime("%H-%M-%S")
        else:
            seg.text = now.strftime("%H %M %S")

        time.sleep(interval)

def main():
    # create seven segment device
    serial = spi(port=0, device=0, gpio=noop())
    device = max7219(serial, cascaded=1)
    seg = sevensegment(device)

    # Digit futzing
    date(seg)
    time.sleep(5)
    clock(seg, seconds=10)

while True: 

    if __name__ == '__main__':
        main()
cleanup()

Actual behaviour

It runs fine for a few hours, then it stops with the following message: OSError: [Errno 24] Too many open files.

Traceback (most recent call last):
  File "luna7datetime.py", line 60, in <module>
  File "luna7datetime.py", line 45, in main
  File "/usr/local/lib/python3.5/dist-packages/luma/core/interface/serial.py", line 280, in __init__
OSError: [Errno 24] Too many open files

Help would be appreciated. Thank you.

rm-hull commented 5 years ago

I think the problem is that the serial interface and the device are continuously re-initialized inside the while loop: this is what is eventually causing the OSError. The latter part of the program would be better written as:

def main():
    # create seven segment device
    serial = spi(port=0, device=0, gpio=noop())
    device = max7219(serial, cascaded=1)
    seg = sevensegment(device)

    while True: 
        # Digit futzing
        date(seg)
        time.sleep(5)
        clock(seg, seconds=10)

if __name__ == '__main__':
    main()
    cleanup()
linuxminty commented 5 years ago

Thank you, rm-hull, for your prompt and helpful reply. Your suggested code has now been running successfully for a longer time than my previous attempts, so I think you've diagnosed the problem accurately and the revised code is working as it should. It's extremely unlikely that I would have sorted this out on my own. I'm very grateful for your assistance! Thanks again.

rm-hull commented 5 years ago

Glad it's working. Will now close this issue. Any other questions/issues: please raise a new ticket!