IndexError: image index out of range Unicorn Hat Mini

Running the python code posted below, at seems like random intervals I get the following error. Which I am lost with trying to figure out what is causing it?

Traceback (most recent call last):
  File "/home/pi/mini_clock.py", line 64, in <module>
    if image.getpixel((x + offset_x, y)) == 255:
  File "/usr/lib/python3/dist-packages/PIL/Image.py", line 1333, in getpixel
    return self.im.getpixel(xy)
IndexError: image index out of range

The code below is a modified version of the text.py file found in the examples for the Unicorn hat Mini.

#!/usr/bin/env python3
import time, datetime
import sys

from PIL import Image, ImageDraw, ImageFont
from unicornhatmini import UnicornHATMini

unicornhatmini = UnicornHATMini()

rotation = 180
if len(sys.argv) > 1:
    try:
        rotation = int(sys.argv[1])
    except ValueError:
        print("Usage: {} <rotation>".format(sys.argv[0]))
        sys.exit(1)

unicornhatmini.set_rotation(rotation)
display_width, display_height = unicornhatmini.get_shape()

print("{}x{}".format(display_width, display_height))

unicornhatmini.set_brightness(0.5)

font = ImageFont.truetype("5x7.ttf", 8)


offset_x = 0

while True:

    text = time.strftime("%A %B %-d %-I:%M%p")

    text_width, text_height = font.getsize(text)

    image = Image.new('P', (text_width + display_width + display_width, display_height), 0)
    draw = ImageDraw.Draw(image)

    

    draw.text((display_width, -1), text, font=font, fill=255)
    
    for y in range(display_height):
        for x in range(display_width):
            if image.getpixel((x + offset_x, y)) == 255:
                unicornhatmini.set_pixel(x, y, 0, 255, 0)
            else:
                unicornhatmini.set_pixel(x, y, 0, 0, 0)

    offset_x += 1
    if offset_x + display_width > image.size[0]:
        offset_x = 0

    unicornhatmini.show()
    time.sleep(0.05)

Trying a new version as a test.I have a hunch as to what might be happening.
With the old code the text / image was being written to the buffer over and over while it was simultaneously being read out and displayed. Which I think corrupted the saved image.
With this code the text= and draw image only happens just before it starts to show the message. And doesn’t get updated again until the end when it starts over. I’m hoping that’s what’s happening, its running now on mine and keeping correct time.
It should, save date time > display date and time > update date and time > display date and time > etc.

#!/usr/bin/env python3
import time, datetime
import sys

from PIL import Image, ImageDraw, ImageFont
from unicornhatmini import UnicornHATMini

unicornhatmini = UnicornHATMini()

rotation = 180
if len(sys.argv) > 1:
    try:
        rotation = int(sys.argv[1])
    except ValueError:
        print("Usage: {} <rotation>".format(sys.argv[0]))
        sys.exit(1)

unicornhatmini.set_rotation(rotation)
display_width, display_height = unicornhatmini.get_shape()

print("{}x{}".format(display_width, display_height))

unicornhatmini.set_brightness(0.5)

font = ImageFont.truetype("5x7.ttf", 8)

offset_x = 0

while True:

    if offset_x == 0:
        text = time.strftime("%A %B %-d %-I:%M %p")
        text_width, text_height = font.getsize(text)
        image = Image.new('P', (text_width + display_width + display_width, display_height), 0)
        draw = ImageDraw.Draw(image)
        draw.text((display_width, -1), text, font=font, fill=255)
    else:
        
        for y in range(display_height):
            for x in range(display_width):
                if image.getpixel((x + offset_x, y)) == 255:
                    unicornhatmini.set_pixel(x, y, 0, 255, 0)
                else:
                    unicornhatmini.set_pixel(x, y, 0, 0, 0)

    offset_x += 1
    if offset_x + display_width > image.size[0]:
        offset_x = 0

    unicornhatmini.show()
    time.sleep(0.05)

So far so good, its been running for 5+ hours without any issues. I guess I should have said what the above code does. It displays the day, date, time in a scrolling message on the Unicorn Hat Mini. I’ll leave it running until I hit the sack tonight. I won’t be posting back here unless I have an issue.

Script is running, let’s hope it runs until morning :)

Other question, I put the script in autostart with this method: [raspberrypi-spy.co.uk]

And get the following error after boot:

Traceback (most recent call last):
File “/home/pi/unicornhatmini-python/examples/textclock.py”, line 7, in
from PIL import Image, ImageDraw, ImageFont
ImportError: No module named PIL

Why it doesn’t work in autostart? If I run the script manual there is no problem at all.

Mine has been running now for 7+ hours with no issues.
I run my python files on boot via crontab. Which I was just about to setup.
From a terminal window I run
sudo crontab -e
and add the following line
@reboot python3 /home/pi/scroll_clock.py &

Edit the @reboot line to your file name and path.

1 Like

I’ll be posting new code in our other thread with a shutdown option mapped to the X button. And a Dim Bright option on the A and B buttons. I have to test it first.

Sadly it doesn’t work for me, the Unicorn HAT Mini doesn’t show anything. This is my crontab:

> # Edit this file to introduce tasks to be run by cron.
> #
> # Each task to run has to be defined through a single line
> # indicating with different fields when the task will be run
> # and what command to run for the task
> #
> # To define the time you can provide concrete values for
> # minute (m), hour (h), day of month (dom), month (mon),
> # and day of week (dow) or use '*' in these fields (for 'any').
> #
> # Notice that tasks will be started based on the cron's system
> # daemon's notion of time and timezones.
> #
> # Output of the crontab jobs (including errors) is sent through
> # email to the user the crontab file belongs to (unless redirected).
> #
> # For example, you can run a backup of all your user accounts
> # at 5 a.m every week with:
> # 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
> #
> # For more information see the manual pages of crontab(5) and cron(8)
> #
> # m h  dom mon dow   command
> 
> @reboot python3 /home/pi/unicornhatmini-python/examples/textclock.py &

Any idea what could be the problem?

Not working for me either, just a blank display?
This has worked for me in the past on several different Pi builds.
I don’t know why it isn’t now?

EDIT: I turned off the splash screen and set it to boot to command line.
I can’t see anything on screen that hints at why it doesn’t work?
This is giving me a headache so I’m packing it in for tonight.

Mine is
@reboot python3 /home/pi/scroll_clock.py &
If I open a terminal window and run
python3 /home/pi/scroll_clock.py
It works? Very confused at this point?

EDIT: I started a thread on this on the Pi Foundation forum.
https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=276808

Script still up and running :) Let’s hope they have an answer at the other forum soon!

That error we were getting was from me just clip and pasting code. Code that I didn’t know what it was really doing? ;) After I sat down and figured out what it did, I made changes that hopefully fixed it.

I’m going to try a few things latter on today when I get a chance.
I’m going to leave out the & and just try
@reboot python3 /home/pi/scroll_clock.py

I’m also going to make up a script file that calls up the python file, do_this.sh
Make it executable, and run that from crontab. I had to do something similar on my motion eye setup with my pan tilt python scripts. My python positioning files did nothing when run directly, but worked fine when called up from a non python script.

It was sujested to change the crontab entry to this
@reboot python3 /home/pi/scroll_clock.py >> /home/pi/error.txt 2>&1
Then look at the error.txt file, if one is generated, for possible answers.
It will be a few hours before I can give it a try though. I have other stuff I have to do first.

I did as they advised, and got following error:

Traceback (most recent call last):
File “/home/pi/unicornhatmini-python/examples/textclock.py”, line 55, in
font = ImageFont.truetype(“5x7.ttf”, 8)
File “/usr/local/lib/python3.7/dist-packages/PIL/ImageFont.py”, line 648, in truetype
return freetype(font)
File “/usr/local/lib/python3.7/dist-packages/PIL/ImageFont.py”, line 645, in freetype
return FreeTypeFont(font, size, index, encoding, layout_engine)
File “/usr/local/lib/python3.7/dist-packages/PIL/ImageFont.py”, line 194, in init
font, size, index, encoding, layout_engine=layout_engine
OSError: cannot open resource

Could it have to do with some rights for the files? That crontab doesn’t have the rights to open files the way I am allowed when I logged in?

I got the same error

Traceback (most recent call last):
  File "/home/pi/scroll_clock.py", line 58, in <module>
    font = ImageFont.truetype("5x7.ttf", 8)
  File "/usr/lib/python3/dist-packages/PIL/ImageFont.py", line 280, in truetype
    return FreeTypeFont(font, size, index, encoding, layout_engine)
  File "/usr/lib/python3/dist-packages/PIL/ImageFont.py", line 145, in __init__
    layout_engine=layout_engine)
OSError: cannot open resource

If I change
font = ImageFont.truetype(“5x7.ttf”, 8)
to
font = ImageFont.load_default()
My file runs from crontab. It looks awful on the LED Matrix, but it runs.
I don’t know what this means or what the answer is?

Same here, it would maybe be possible to change the default font but I think there should be an easier way to solve this problem

I found a solution, it looks like you need to include the path to the file.
I changed
font = ImageFont.truetype(“5x7.ttf”, 8)
to
font = ImageFont.truetype(“/home/pi/5x7.ttf”, 8)
and now it runs on boot. =)

For you I guess it’s
font = ImageFont.truetype(“/home/pi/unicornhatmini-python/examples/5x7.ttf”, 8)`

It works! Although I always find it weird that Linux works the way it works. Starting sth. manual and everything is fine, starting sth. via crontab and you have to change this and that.

This was a head scratcher for sure? Going to be taking a break from this now.

1 Like