Adjust Python examples

Went though what I had on hand and built a test setup for my Unicorn Mini, breakout garden mini and pi zero.
I just happened to have a Mini Black Hat Hack3r board with a male 90 on one end. It’s the end where you would normally connect the ribbon cable too. I plugged my Unicorn Mini in there as that puts it vertical for easy viewing. The breakout Garden mini went on next in the first pHat slot with the BME280 in it. I also just happened to have a PI Zero W with a female header on its bottom side. That lets me plug it into the second pHat spot and all its jacks are conveniently pointing out the back. Well technically the front I guess, my mini black hat hacker is turned 180,its reversed from how you would normally orientate it.

Did a quick test run and then swapped out the unicorn Mini for the Unicorn HD.

Feeling a bit sore today so I’m not sure how much coding I’m going to do. I did all my yard work yesterday so the next couple of days are free time to tinker. =)

1 Like

Looking really nice that way. Mine is still running the clock and I kept it in the Pibow with the diffuser. For now still very satisfied with it :)

Now that I have the Unicorn HD on that testing setup I could put the Mini back on the Pi Zero and run the clock. I don’t have a spare power supply at the moment though. I have way more Pi’s than I have power supplies to power them lol.

I did a little bit of tinkering today, didn’t really accomplish much.
Tried to use a different font but all I got was a bunch of python errors.
Then when I had a line of code that didn’t error, it still didn’t display correctly.
I put it away for now, but will get back to it. I downloaded a couple of LED DOT Matrix Fonts today, that “should” work. Once I figure out the correct syntax etc.

A long overdue Pimoroni order arrived today with my Arduino Starter kit.
That distracted me a bit and got me a little sidetracked. ;)

I started with some rough code that works with the Unicorn HD.
I changed the lines = in the text.py example to show the day, date, time.
And changed the font from FreeSansBold.ttf to FreeSans.ttf
And basically put most of the code in a while True loop so it repeats.
It’s was a bodge job at best, but it works and the time updates.
All I got was red for a color though and there was a delay between the message starting again. I have since updated that code to something better and updated what I had posted earlier below. If you clip and pasted it earlier, grab the new code below.
Fixed the color issue so what color you want can be set by the r, g, b = line.
And fixed the delay between scrolls. =)

#!/usr/bin/env python

import time
from sys import exit

try:
    from PIL import Image, ImageDraw, ImageFont
except ImportError:
    exit('This script requires the pillow module\nInstall with: sudo pip install pillow')

import unicornhathd

unicornhathd.rotation(90)
unicornhathd.brightness(0.6)

FONT = ('/usr/share/fonts/truetype/freefont/FreeSans.ttf', 12)

r, g, b = (0, 255, 255)

while True:

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

    width, height = unicornhathd.get_shape()

    text_x = width
    text_y = 2


    font_file, font_size = FONT

    font = ImageFont.truetype(font_file, font_size)

    text_width, text_height = width, 0

    text = time.strftime("It's %A %B %-d %-I:%M:%p")
    
    w, h = font.getsize(text)
    text_width += w + width
    text_height = max(text_height, h)
    
    image = Image.new('RGB', (text_width, max(16, text_height)), (0, 0, 0))
    draw = ImageDraw.Draw(image)

    offset_left = 0

    draw.text((text_x + offset_left, text_y), text, font=font)

    offset_left += font.getsize(text)[0] + width

    for scroll in range(text_width - width):
        for x in range(width):
            for y in range(height):
                pixel = image.getpixel((x + scroll, y))
                r, g, b = [int(n) for n in pixel]
                unicornhathd.set_pixel(width - 1 - x, y, r, g, b)

        unicornhathd.show()
        time.sleep(0.01)

I haven’t done any extended run of the above code. I have plans for that today. I want to make sure we don’t get that same weird error we got on the Mini. Might have to stick a print statement in there to see how often the text = is being run. Ideally it should only run once per scroll.
I also had a go at modifying the Mini scroll clock py file and changing all the references to unicornhathd. There were a few other edits needed too. It didn’t like the font code line from the HD py file so I went back to the 7x5 line of code. That got it working with small text. But, and I’m not making this up, you’d have to hold it in a mirror to read it. The text was flipped over, not rotated flipped? Likely to do with how the row columns are numbered on the HD versus the Mini. I’m going to double check which corner is LED 0,0 latter on, make a note, and then run the above code for an extended period.

EDIT: Looks like I don’t have the color totally working, changing the r, g, b values does nothing?
It’s something in the following code that needs to be changed, that’s overriding the r, g, b = stement.

 for scroll in range(text_width - width):
        for x in range(width):
            for y in range(height):
                pixel = image.getpixel((x + scroll, y))
                r, g, b = [int(n) for n in pixel]
                unicornhathd.set_pixel(width - 1 - x, y, r, g, b)

If I comment out the r, g, b = [int(n) for n in pixel] line all I get is all the leds lit up in the one color. At one point I got the same flipped / mirrored text I got when playing with the Mini scroll file.

On the plus side the text = is only run between messages.

EDIT:
@Shoe helped me sort it out. the draw text line needs to be edited as follows
draw.text((text_x + offset_left, text_y), text, font=font, fill=(r, g, b))
And the r, g, b = line moved into the while true section. Right at the top under the text= seems to work OK.

EDIT: No. 2 Here is full code that will also show temperature, humidity, and barometric pressure readings from a BME280. I have to add it to this post as I’m only allowed 3 in a row. All I have to do now is edit the references to BME280 to BME680 and I can use this on my portable weather clock setup. It will replace my Sense Hat. =)

#!/usr/bin/env python

import time
from sys import exit

from PIL import Image, ImageDraw, ImageFont

import unicornhathd

try:
    from smbus2 import SMBus
except ImportError:
    from smbus import SMBus
from bme280 import BME280

bus = SMBus(1)
bme280 = BME280(i2c_dev=bus)

unicornhathd.rotation(90)
unicornhathd.brightness(0.6)

FONT = ('/usr/share/fonts/truetype/freefont/FreeSans.ttf', 12)

while True:

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

    #print("time updated")

    width, height = unicornhathd.get_shape()

    text_x = width
    text_y = 2


    font_file, font_size = FONT

    font = ImageFont.truetype(font_file, font_size)

    text_width, text_height = width, 0

    text = time.strftime("It's %A %B %-d %-I:%M:%p")
    
    w, h = font.getsize(text)
    text_width += w + width
    text_height = max(text_height, h)

    
    image = Image.new('RGB', (text_width, max(16, text_height)), (0, 0, 0))
    draw = ImageDraw.Draw(image)

    r, g, b =(0, 255, 255)
    
    offset_left = 0
    

    draw.text((text_x + offset_left, text_y), text, font=font, fill=(r, g, b))
    #draw.text((text_x + offset_left, text_y), text, font=font)

    offset_left += font.getsize(text)[0] + width

    for scroll in range(text_width - width):
        for x in range(width):
            for y in range(height):
                pixel = image.getpixel((x + scroll, y))
                r, g, b = [int(n) for n in pixel]
                unicornhathd.set_pixel(width - 1 - x, y, r, g, b)

        unicornhathd.show()
        time.sleep(0.01)


    T = bme280.get_temperature()
    T = round(T)
          
    if T <= 0: 
        r, g, b = [0, 0, 255]    # Blue
        text = ("and its very Cold @ %sc") % (T)
    elif T > 0 and T < 13:
        r, g, b, = [255, 255, 0] # Yellow
        text = ("and its cool at %sc") % (T)
    elif T >= 13 and T < 25:
        r, g, b = [0, 255, 0]    # Green
        text = ("and the Temperature is %sc") % (T)
    elif T >= 25 and T < 30:
        r, g, b = [255, 50, 0]  # Orange
        text = ("and its Hot @ %sc") % (T)
    elif T >= 30:
        r, g, b = [255, 0, 0]    # Red
        text = ("and its very Hot @ %sc") % (T)

    width, height = unicornhathd.get_shape()

    text_x = width
    text_y = 2


    font_file, font_size = FONT

    font = ImageFont.truetype(font_file, font_size)

    text_width, text_height = width, 0
        
    w, h = font.getsize(text)
    text_width += w + width
    text_height = max(text_height, h)

    
    image = Image.new('RGB', (text_width, max(16, text_height)), (0, 0, 0))
    draw = ImageDraw.Draw(image)
   
    offset_left = 0
    

    draw.text((text_x + offset_left, text_y), text, font=font, fill=(r, g, b))
    #draw.text((text_x + offset_left, text_y), text, font=font)

    offset_left += font.getsize(text)[0] + width

    for scroll in range(text_width - width):
        for x in range(width):
            for y in range(height):
                pixel = image.getpixel((x + scroll, y))
                r, g, b = [int(n) for n in pixel]
                unicornhathd.set_pixel(width - 1 - x, y, r, g, b)

        unicornhathd.show()
        time.sleep(0.01)


    H = bme280.get_humidity() 
    H = round(H)

    if H < 30:
        r, g, b = [255, 0, 0]    # Red
        text = ("with Low %s%% Humidity") % (H)
    elif H >= 30 and H <= 60:
        r, g, b = [0, 255, 0]    # Green
        text = ("with %s%% Humidity") % (H)
    elif H > 60 and H < 80:
        r, g, b = [255, 255, 0]  # Yellow
        text = ("with High %s%% Humidity") % (H)
    elif H >= 80:
        r, g, b = [255, 0, 0]    # Red
        text = ("with Very High %s%% Humidity") % (H)

    width, height = unicornhathd.get_shape()

    text_x = width
    text_y = 2


    font_file, font_size = FONT

    font = ImageFont.truetype(font_file, font_size)

    text_width, text_height = width, 0
        
    w, h = font.getsize(text)
    text_width += w + width
    text_height = max(text_height, h)

    
    image = Image.new('RGB', (text_width, max(16, text_height)), (0, 0, 0))
    draw = ImageDraw.Draw(image)
   
    offset_left = 0
    

    draw.text((text_x + offset_left, text_y), text, font=font, fill=(r, g, b))
    #draw.text((text_x + offset_left, text_y), text, font=font)

    offset_left += font.getsize(text)[0] + width

    for scroll in range(text_width - width):
        for x in range(width):
            for y in range(height):
                pixel = image.getpixel((x + scroll, y))
                r, g, b = [int(n) for n in pixel]
                unicornhathd.set_pixel(width - 1 - x, y, r, g, b)

        unicornhathd.show()
        time.sleep(0.01)

    p = bme280.get_pressure() 
    P = round(p)
            
    if P > 0 and P < 982:             # Very Low
        r, g, b = [255, 0, 0]         # Red
        text = ("Baromiter is Very Low@ %smb : Storm Watch") % (P)
    elif P >= 982 and P < 1004:       # Low
        r, g, b = [255, 255, 0]       # Yellow
        text = ("Barometer is Low @ %smb : Posible Precipitation") % (P)
    elif P >= 1004 and P < 1026:      # Mid Range
        r, g, b = [0, 255, 0]         # Green
        text = ("Barometer is @ %smb") % (P)
    elif P >= 1026 and P < 1048:      # High
        r, g, b = [0, 0, 255]         # Blue
        text = ("Barometer is High @ %smb") % (P)
    elif P >= 1048:                   # Very High
        r, g, b = [255, 50, 0]        # Orange
        text = ("Barometer is Very High @ %smb") % (P)


    width, height = unicornhathd.get_shape()

    text_x = width
    text_y = 2


    font_file, font_size = FONT

    font = ImageFont.truetype(font_file, font_size)

    text_width, text_height = width, 0
        
    w, h = font.getsize(text)
    text_width += w + width
    text_height = max(text_height, h)

    
    image = Image.new('RGB', (text_width, max(16, text_height)), (0, 0, 0))
    draw = ImageDraw.Draw(image)
   
    offset_left = 0
    

    draw.text((text_x + offset_left, text_y), text, font=font, fill=(r, g, b))
    #draw.text((text_x + offset_left, text_y), text, font=font)

    offset_left += font.getsize(text)[0] + width

    for scroll in range(text_width - width):
        for x in range(width):
            for y in range(height):
                pixel = image.getpixel((x + scroll, y))
                r, g, b = [int(n) for n in pixel]
                unicornhathd.set_pixel(width - 1 - x, y, r, g, b)

        unicornhathd.show()
        time.sleep(0.01)

EDIT: No 3. I wasn’t happy with the size of the text being displayed, it wasn’t using the full height. I played around with some of the settings and finally settled on what I think looks OK.
First I changed

    text_x = width
    text_y = 2

to

    text_x = width
    text_y = -2

this moved it up to the top of the screen. Then I changed the points in the font.
FONT = ('/usr/share/fonts/truetype/freefont/FreeSans.ttf', 12)
became
FONT = ('/usr/share/fonts/truetype/freefont/FreeSans.ttf', 16)
Close up its a bit blotchy, but from a distance it doesn’t look too bad.

I need to speed up the scroll speed though.