Adjust Python examples

Haha I have the problem all the time with forgetting what I did and how I did it, and end sometimes up with installing Raspberry OS 3 times a day. I also put the display on blue light, until I"m bored of it then I probably switch to green or red or sth. in between.
The weather clock sounds interesting, especially the color changes!

The Y button is so far unused, you could code it to change color when pressed. ;)
Most of my Pi build pictures are here if you want to have a look see.
https://1drv.ms/u/s!AjOYwiwlwDtpgUMsp2qnevKpGEHb?e=Wd9eSc

lol, itā€™s my Microsoft Public OneDrive folder.

I have two weather clocks, one stand alone indoor one and a portable battery powered version. The indoor one doesnā€™t have the light or UV sensor on it. The LED shim can be set to show temperature or barometric pressure. Toggled with the Sense H joystick. Itā€™s usually set to show the pressure in the winter, and temperature in the summer.

To put colorchange on the Y button might be a nice thing to try, next to my Ubercorn, Pirate Audio and Sphero RVR / Pi projects, Too many things, too less time. But some nice projects you did!

I hear you. My wife just chuckles to herself when Iā€™m taking things out on my back deck to tinker with in under my gazebo. I make half a dozen or so trips taking stuff out. Laptop, portable weather clock, maybe my Pirate radio and one or two other Pi projects. Then carry it all back in a couple of hours latter. =)
I have finally got all the pieces for this,
https://learn.pimoroni.com/tutorial/sandyj/build-an-itty-bitty-beat-box
so its moved to the top of my list of projects to finish. Just the software to install and setup.
After that I have some breakout garden stuff I want to get back too.

Pressing Y button now cycles though different colors. Changing the Y = line changes the default color it will start with, Y = 3 is Blue. Editing the r, g, b = lines will change the color assigned to that value for Y. I donā€™t know why, timing I guess, but the occasional button press is missed? It doesnā€™t crash the program so not a big deal.

#!/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

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 = 3 # Blue
B = 0.5

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 > 4:
        Y = 0

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

    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, 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 13th 2020
# added color chnage function to Y button
# run sudo crontab -e
# add
# @reboot python3 /home/pi/scroll_clock.py &

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.