Adjust Python examples

Nice one! took me some time to get it working because I thought it was only a small change in the script but then it didn’t work. So had to read the script good and then found all the changes and now it works :)

That was one of the easier changes. No more buttons left now though, lol. Unless you add a button shim etc.
Hmm, that would be one way to avoid having to drill holes in the diffuser, and no having to use a toothpick.

Haha yeah button shim looks like it fits perfectly in the pibow coupe and diffuser on top

Added one more color option for Y = 5.
I’m not saying what it does though.
This was really hard to pull off.

#!/usr/bin/env python3
import sys
import os
import time, datetime
import RPi.GPIO as GPIO

from colorsys import hsv_to_rgb

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

unicornhatmini = UnicornHATMini()

GPIO.setmode(GPIO.BCM)  
GPIO.setwarnings(False)
GPIO.setup(5, GPIO.IN, pull_up_down = GPIO.PUD_UP)  # A
GPIO.setup(6, GPIO.IN, pull_up_down = GPIO.PUD_UP)  # B
GPIO.setup(16, GPIO.IN, pull_up_down = GPIO.PUD_UP) # X
GPIO.setup(24, GPIO.IN, pull_up_down = GPIO.PUD_UP) # Y

X = 0
Y = 0
B = 0.3

def Dim(channel):  
    global B
    B = B - 0.1

    if B <= 0.1:
        B = 0.1

    unicornhatmini.set_brightness(B)

def Bright(channel):  
    global B
    B = B + 0.1

    if B >= 1.0:
        B = 1.0

    unicornhatmini.set_brightness(B)  

def Shutdown(channel):  
    global X
    X = 1

def color(channel):  
    global Y
    Y = Y + 1
    
GPIO.add_event_detect(5, GPIO.FALLING, callback = Dim, bouncetime = 2000)
GPIO.add_event_detect(6, GPIO.FALLING, callback = Bright, bouncetime = 2000)
GPIO.add_event_detect(16, GPIO.FALLING, callback = Shutdown, bouncetime = 2000)
GPIO.add_event_detect(24, GPIO.FALLING, callback = color, bouncetime = 2000)

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()

unicornhatmini.set_brightness(B)

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

offset_x = 0

while True:

    if Y > 5:
        Y = 0

    if Y == 0:
        r, g, b = (0, 255, 255)   # Aqua
    elif Y == 1:
        r, g, b = (255, 0, 0)     # Red 
    elif Y == 2:
        r, g, b = (0, 205, 0)     # Green
    elif Y == 3:
        r, g, b = (0, 0, 255)     # Blue  
    elif Y == 4:
        r, g, b = (255, 140, 0)   # Orange

    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)

    if Y == 5:
        
        for y in range(display_height):
            for x in range(display_width):
                hue = (time.time() / 10.0) + (x / float(display_width * 2))
                r, g, b = [int(c * 255) for c in hsv_to_rgb(hue, 1.0, 1.0)]
                if image.getpixel((x + offset_x, y)) == 255:
                    unicornhatmini.set_pixel(x, y, r, g, b)
                else:
                    unicornhatmini.set_pixel(x, y, 0, 0, 0)
    if Y < 5:           

        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, r, g, b)
                else:
                    unicornhatmini.set_pixel(x, y, 0, 0, 0)

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

    if X == 1:
        unicornhatmini.set_all(0, 0, 0)
        unicornhatmini.show()
        os.system("sudo shutdown now -P")
        time.sleep(30)

    unicornhatmini.show()
    time.sleep(0.05)
    
# Last edited on June 14th 2020
# added color chnage function to Y button
# run sudo crontab -e
# add
# @reboot python3 /home/pi/scroll_clock.py &

Again took some time to see all the changes in the code ;) but wow, what a nice colorchange now. I also checked the option for the button shim, might need some modification on the pibow but then it should fit, the only problem is that I then also have to build a little stand so I can flip the Pi, put a 90 degree usb-cable and the buttons are on top.

To be honest I borrowed that code from the text.py example.
It took a lot of trial and error to get it integrated into my code though.

I noticed that too, if you use the button shim you have to flip the Unicorn Mini 180.
For my setup I would have to and that puts my Pi Zero’s power jack facing down.
Not an ideal setup for me so I won’t be adding a button shim any time soon.

Just FYI the button shim needs to be soldered.

Ah damn I thought it might work like the fan shim, just put it on the Pi headers and the HAT on top. My solder skills are on the same level as my Python skills. Mistakes in Python are easier to correct than mistakes during soldering.

I’m not all that fussy for that friction fit shim stuff. It’s about 50 50 here Fan Shim wise, some work some don’t. I have one I had to solder to a header to get it fully functional.
If the Fan shim had the full length header like the LED Shim I think it would have a better chance of working right out of the box.
Also think its misleading calling the Button Shim a shim, as it has to be soldered to work.

EDIT: I’m a retired electronic technician, soldering is easy peasy for me, been doing it for 40+ years lol.

I got my temperature readout added. What a Time I had getting that to work.
It would get stuck and just endlessly repeat one of the other message.
Humidity and pressure readouts are next.

The color cycle function is removed from this file, and I have to add back in the incremental brightness. I’ll strip out the exit code once I get it finalized.

#!/usr/bin/env python3
import sys
import os
import time, datetime
import RPi.GPIO as GPIO

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

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

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

unicornhatmini = UnicornHATMini()

GPIO.setmode(GPIO.BCM)  
GPIO.setwarnings(False)
GPIO.setup(5, GPIO.IN, pull_up_down = GPIO.PUD_UP)  # A
GPIO.setup(6, GPIO.IN, pull_up_down = GPIO.PUD_UP)  # B
GPIO.setup(16, GPIO.IN, pull_up_down = GPIO.PUD_UP) # X
GPIO.setup(24, GPIO.IN, pull_up_down = GPIO.PUD_UP) # Y

# button_map
#  5: "A",
#  6: "B",
# 16: "X",
# 24: "Y"}

X = 0
Y = 0
M = 0

def Dim(channel):  
    unicornhatmini.set_brightness(0.5)

def Bright(channel):  
    unicornhatmini.set_brightness(1.0)

def Shutdown(channel):  
    global X
    X = 1

def Exit(channel):  
    global Y
    Y = 1           

GPIO.add_event_detect(5, GPIO.FALLING, callback = Dim, bouncetime = 2000)
GPIO.add_event_detect(6, GPIO.FALLING, callback = Bright, bouncetime = 2000)
GPIO.add_event_detect(16, GPIO.FALLING, callback = Shutdown, bouncetime = 2000)
GPIO.add_event_detect(24, GPIO.FALLING, callback = Exit, bouncetime = 2000)

rotation = 0
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()

unicornhatmini.set_brightness(0.5)

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

offset_x = 0

while True:

    if offset_x == 0 and M == 0:
        text = time.strftime("It's %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)
        r, g, b = (0, 255, 255)

    elif offset_x == 0 and M == 1:
        T = bme280.get_temperature() 
        T = round(T)
          
        if T <= 0: 
            r, g, b = [0, 0, 255]    # Blue
        elif T > 0 and T < 13:
            r, g, b, = [255, 255, 0] # Yellow
        elif T >= 13 and T < 25:
            r, g, b = [0, 255, 0]    # Green
        elif T >= 25 and T < 30:
            r, g, b = [255, 50, 0]  # Orange
        elif T >= 30:
            r, g, b = [255, 0, 0]    # Red

        text = ("and the Temperature is %sc") % (T)
        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, r, g, b)
                else:
                    unicornhatmini.set_pixel(x, y, 0, 0, 0)

    unicornhatmini.show()
    time.sleep(0.05)
                    

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

    if M == 2:
        M = 0
 
    if X == 1:
        unicornhatmini.set_all(0, 0, 0)
        unicornhatmini.show()
        os.system("sudo shutdown now -P")
        time.sleep(30)

    if Y == (1):
        unicornhatmini.set_all(0, 0, 0)
        unicornhatmini.show()        
        raise SystemExit
        time.sleep(30)        

    

# Last edited on June 16th 2020
# added temperature display
# 
# run sudo crontab -e
# add
# @reboot python3 /home/pi/scroll_clock.py

Looks nice, do I understand right that the "and the Temperature is %sc" part is an PIL image? And the %sc is something imported from the SMBus/bme280?

The “and the Temperature is” displays as text. The %s displays what’s after the other % sign out side the brackets. % (T) displays the variable T which is the rounded off temperature. Taken from the BME280
T = bme280.get_temperature()
T = round(T)
And the c (more text) to denote degrees Celsius. Have a look at this.
This will work with a BME680 etc, with some code changes.

#!/usr/bin/env python3
import sys
import os
import time, datetime
import RPi.GPIO as GPIO

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

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

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

unicornhatmini = UnicornHATMini()

GPIO.setmode(GPIO.BCM)  
GPIO.setwarnings(False)
GPIO.setup(5, GPIO.IN, pull_up_down = GPIO.PUD_UP)  # A
GPIO.setup(6, GPIO.IN, pull_up_down = GPIO.PUD_UP)  # B
GPIO.setup(16, GPIO.IN, pull_up_down = GPIO.PUD_UP) # X
GPIO.setup(24, GPIO.IN, pull_up_down = GPIO.PUD_UP) # Y

# button_map
#  5: "A",
#  6: "B",
# 16: "X",
# 24: "Y"}

X = 0
Y = 0
M = 0

def Dim(channel):  
    unicornhatmini.set_brightness(0.5)

def Bright(channel):  
    unicornhatmini.set_brightness(1.0)

def Shutdown(channel):  
    global X
    X = 1

def Exit(channel):  
    global Y
    Y = 1           

GPIO.add_event_detect(5, GPIO.FALLING, callback = Dim, bouncetime = 2000)
GPIO.add_event_detect(6, GPIO.FALLING, callback = Bright, bouncetime = 2000)
GPIO.add_event_detect(16, GPIO.FALLING, callback = Shutdown, bouncetime = 2000)
GPIO.add_event_detect(24, GPIO.FALLING, callback = Exit, bouncetime = 2000)

rotation = 0
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()

unicornhatmini.set_brightness(0.5)

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

offset_x = 0

while True:

    if offset_x == 0 and M == 0:
        text = time.strftime("It's %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)
        r, g, b = (0, 255, 255)

    elif offset_x == 0 and M == 1:
        T = bme280.get_temperature() 
        T = round(T)
          
        if T <= 0: 
            r, g, b = [0, 0, 255]    # Blue
        elif T > 0 and T < 13:
            r, g, b, = [255, 255, 0] # Yellow
        elif T >= 13 and T < 25:
            r, g, b = [0, 255, 0]    # Green
        elif T >= 25 and T < 30:
            r, g, b = [255, 50, 0]  # Orange
        elif T >= 30:
            r, g, b = [255, 0, 0]    # Red

        text = ("and the Temperature is %sc") % (T)
        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)

    elif offset_x == 0 and M == 2:
        H = bme280.get_humidity() 
        H = round(H)
        
        if H < 30:
            r, g, b = [255, 0, 0]    # Red
        elif H >= 30 and H <= 60:
            r, g, b = [0, 255, 0]    # Green
        elif H > 60 and H < 80:
            r, g, b = [255, 255, 0]  # Yellow
        elif H >= 80:
            r, g, b = [255, 0, 0]    # Red

        text = ("with %s%% Humidity") % (H)
        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)

    elif offset_x == 0 and M == 3:
        p = bme280.get_pressure() 
        P = round(p)
            
        if P > 0 and P < 982:             # Very Low
            r, g, b = [255, 0, 0]         # Red
        elif P >= 982 and P < 1004:       # Low
            r, g, b = [255, 255, 0]       # Yellow
        elif P >= 1004 and P < 1026:      # Mid Range
            r, g, b = [0, 255, 0]         # Green
        elif P >= 1026 and P < 1048:      # High
            r, g, b = [0, 0, 255]         # Blue
        elif P >= 1048:                   # Very High
            r, g, b = [255, 50, 0]        # Orange

        text = ("@ %smb Pressure") % (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, r, g, b)
                else:
                    unicornhatmini.set_pixel(x, y, 0, 0, 0)

    unicornhatmini.show()
    time.sleep(0.05)
                    

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

    if M == 4:
        M = 0
 
    if X == 1:
        unicornhatmini.set_all(0, 0, 0)
        unicornhatmini.show()
        os.system("sudo shutdown now -P")
        time.sleep(30)

    if Y == (1):
        unicornhatmini.set_all(0, 0, 0)
        unicornhatmini.show()        
        raise SystemExit
        time.sleep(30)        

    

# Last edited on June 16th 2020
# added temperature humididty and pressure display
# 
# run sudo crontab -e
# add
# @reboot python3 /home/pi/scroll_clock.py

Woot, I an pumped right now. I also managed to add some custom messages to the pressure messages. is very low : Storm Watch, is low : Possible Precipitation etc.
Next step is to try and port this over to run on my Unicorn Hat HD. =)

If you get it running on te Unicorn HAT HD let me know, because then it should work on my Ubercorn, and I have a good reason to buy those sensors :)

I should be trying to port to my Unicorn HD some time latter this week or early next week.
I’ll let you now how it goes.

Finished up the code to move my Unicorn Mini into my portable weather clock. I had a few issues to sort out to get it fully functional. I’m happy with how it works but I have a power issue.
If I power it via an official 2.5A supply plugged into the Pi A+ all is fine. Won’t run on powerboost though, 1A isn’t enough. Even on my power supply plugged into the back I got flashing undervolt warnings.
I have two things to fix. I need to switch to the non charging version of the PowerBoost, it can supply 2A. And I need to replace the power wires going from the PowerBoost to the Pi with heavier ones. I used jumpers and they just aren’t thick enough.
I have one of these and may swap it in place of the powerboost.

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.