Another Blinkt question

Sigh. Such a newbie here…

Plugged my Blinkt into the GPIO. Wrote my python script. Everything is great.

Decided I needed a power button. There’s a tiny bit of space between the board and the Blinkt, so – avoiding the pins that the Blinkt actually uses, I wired up a button.

Button works. Blinkt suddenly doesn’t.

Trying to troubleshoot, I removed the Blinkt and wired four wires from the GPIO to the correct slots on the Blinkt. It lights up, so I know it’s getting power, but doesn’t respond to commands either from the script or through SSH. (Power button still works.)

What the heck am I doing wrong? Probably something ridiculously obvious that’s staring me right in the face…

By power button do you mean a shutdown button? And what pins did you use for it.
Posting the code your using for the Blinkt and button may help.
Code tags are three ` before and after your block of code.

I’m using this tutorial for my button: https://howchoo.com/g/mwnlytk3zmm/how-to-add-a-power-button-to-your-raspberry-pi.

It uses GPIO 6 for ground, but since Blinkt needs that, I moved the ground wire to another ground pin.

Separately, everything works. Together, not so much.

The Blinkt code is just the rainbow.py example script, unmodified. The button script is:


import RPi.GPIO as GPIO
import subprocess


GPIO.setmode(GPIO.BCM)
GPIO.setup(3, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.wait_for_edge(3, GPIO.FALLING)

subprocess.call(['shutdown', '-h', 'now'], shell=False)

I’m starting to wonder if I just use thinner wire…

Just FYI, you don’t have to use GPIO 3. I mention this because GPIO 3 is used by i2c, which I make use of. I’m no expert but I’d avoid that pin just incase its causing issues.
I did this, and its in the python file I run on bootup. I do it all from the one file. Just replace the unicornhathd.clear etc with the equivalent blinkt clear command.

def Shutdown(channel): 
        unicornhathd.clear()
        unicornhathd.show()
        ledshim.clear()
        ledshim.show()
        os.system("sudo shutdown now -P")
        time.sleep(30)    

GPIO.setmode(GPIO.BCM)  
GPIO.setwarnings(False)
GPIO.setup(21, GPIO.IN, pull_up_down = GPIO.PUD_UP) 
GPIO.add_event_detect(21, GPIO.FALLING, callback = Shutdown, bouncetime = 2000)

This is all above the while True:

I use a lot of Proto Zero’s and Perma Proto Hats. I use a stacking header and put them between my Pi and Hat. They give you access to the GPIO pins to connect multiple devices.
ProtoZero – Pimoroni

You can have multiple devices wired up to a single ground pin. Doesn’t hurt to spread them out though. All the ground pins on the Pi are connected to each other.

OK, I tried thinner wire and it worked! I think the wire I had before was just thick enough that it kept the Blinkt from sitting fully on the header pins.

Gonna solder those wires down with the tiniest little beads ever… 😂

Don’t forget that the header pins go through the PCB, so with a bit of care it is perfectly possible to solder wires onto the underside of the pins/board and leave the actual header fully clear.

That was going to be the next thing I tried…and still might be!

Stupid noob question: Where are you putting this python file that runs on bootup? How is it formatted? I’d love to steal your code, but I don’t know where or how. :)

It’s just a normal python file, and I usually just put it in the Home folder.
To have it run on bootup I use crontab.
From a terminal window I run
crontab -e
I pick option 1 nano and add the following to the end of the file
@reboot python3 /home/pi/myfile.py &
ctrl x and y to save.
This is one of mine with a custom shut down. Warning, wall of text to follow, lol.
It’s a slight variation on what I posted above, the if s=0 is the clear and shutdown code.
s is set to 0 by the def shutdown code.

#!/usr/bin/python3

import os
import time, datetime
import bme680
import ledshim
import veml6075
import unicornhathd
import smbus
import RPi.GPIO as GPIO
from sys import exit
from PIL import Image, ImageDraw, ImageFont
from ltr559 import LTR559
ltr559 = LTR559()
unicornhathd.rotation(90)
unicornhathd.brightness(0.5)
ledshim.set_brightness(0.5)
sensor = bme680.BME680()
sensor.set_humidity_oversample(bme680.OS_2X)
sensor.set_pressure_oversample(bme680.OS_4X)
sensor.set_temperature_oversample(bme680.OS_8X)
sensor.set_filter(bme680.FILTER_SIZE_3)
sensor.set_gas_status(bme680.DISABLE_GAS_MEAS)
#sensor.set_gas_heater_temperature(320)
#sensor.set_gas_heater_duration(150)
#sensor.select_gas_heater_profile(0)
bus = smbus.SMBus(1) 
uv_sensor = veml6075.VEML6075(i2c_dev=bus)
uv_sensor.set_shutdown(False)
uv_sensor.set_high_dynamic_range(False)
uv_sensor.set_integration_time('100ms')
FONT = ('/usr/share/fonts/truetype/freefont/FreeSans.ttf', 16)
GPIO.setmode(GPIO.BCM)  
GPIO.setwarnings(False)
GPIO.setup(5, GPIO.IN, pull_up_down = GPIO.PUD_OFF)  
w = 0     # color all white toggle
S = 1

def set_multiple_pixels(indexes, r, g, b):
    for index in indexes:
        ledshim.set_pixel(index, r, g, b)

def Shutdown(channel):  
    global S
    S = (0)

def ledtemp():
    if sensor.get_sensor_data(): 
        t = sensor.data.temperature 
        t = round(t)
        
    if t >= 41:                                        # Realy Hot 
        set_multiple_pixels(range(0,28), 255, 0, 0)    # Red
        M = (t - 68) * (-1)
        # R R R R R R R R R R R R R R R R R R R R R R R R R R R R
    elif t >= 13 and t <= 40:                          # Main
        set_multiple_pixels(range(0,11), 255, 0, 0)    # Red
        set_multiple_pixels(range(11,16), 255, 140, 0) # Orange
        set_multiple_pixels(range(16,28), 0, 255, 0)   # Green
        M = (40 - t)
        # R R R R R R R R R R R O O O O O G G G G G G G G G G G G
    elif t >= -15 and t <=12:                          # Cold 
        set_multiple_pixels(range(0,12), 255, 255, 0)  # Yellow
        set_multiple_pixels(range(12,28), 0, 0, 255)   # Blue
        M = (12 - t)
        # Y Y Y Y Y Y Y Y Y Y Y Y B B B B B B B B B B B B B B B B
    elif t < -15:                                      # Really cold
        set_multiple_pixels(range(0,28), 255, 255, 255)  # White
        M = ((t + 16) * (-1))
        # W W W W W W W W W W W W W W W W W W W W W W W W W W W W
    
    ledshim.set_pixel(M, 0, 0, 0)
    ledshim.show()

def ledpress():
    if sensor.get_sensor_data(): 
        p = sensor.data.pressure 
        p = round(p)

    set_multiple_pixels(range(0,5), 255, 140, 0)       # orange - Very High
    set_multiple_pixels(range(5,11), 0, 0, 255)        # Blue   - High
    set_multiple_pixels(range(11,17), 0, 255, 0)       # Green  - Mid Range
    set_multiple_pixels(range(17,23), 255, 255, 0)     # Yellow - Low
    set_multiple_pixels(range(23,28), 255, 0, 0)       # Red    - Verry Low

    if p > 1070:
        M = 0
    elif p >= 1048 and p < 1070: # Very High  M is 0 - 4
        N = (p - 1048) / 4.7  
        N = round(N)
        M = 4 - N
    elif p >= 1026 and p < 1048: # High       M is 5 - 10
        N = (p - 1026) / 3.9 
        N = round(N)
        M = 10 - N
    elif p >= 1004 and p < 1026: # Mid Range  M is 11 - 16
        N = (p - 1004) / 3.9 
        N = round(N)
        M = 16 - N
    elif p >= 982 and p < 1004:  # Low        M is 17 - 22
        N = (p - 982) / 3.9 
        N = round(N)
        M = 22 - N
    elif p >= 960 and p < 982:   # Very Low   M 23 - 27
        N = (p - 960) / 4.7
        N = round(N)
        M = 27 - N
    elif p < 960:        
        M = 27
    
    ledshim.set_pixel(M, 0, 0, 0)    
    ledshim.show()     
        
GPIO.add_event_detect(5, GPIO.FALLING, callback = Shutdown, bouncetime = 2000)

while True:
    ltr559.update_sensor()
    lux = ltr559.get_lux()
    Lux =("{:06.2f}".format(lux))
    Lux = int(float(Lux))
    Lux = round(Lux)

    if Lux < 4000:
        unicornhathd.brightness(0.5)
        unicornhathd.show()
        ledshim.set_brightness(0.5)
        ledshim.show()
        w = 0
    elif Lux >= 4000 and Lux < 10000:
        unicornhathd.brightness(1.0)
        unicornhathd.show()
        ledshim.set_brightness(1.0)
        ledshim.show()
        w = 0
    elif Lux >= 10000:
        unicornhathd.brightness(1.0)
        unicornhathd.show()
        ledshim.set_brightness(1.0)
        ledshim.show()
        w = 1

    #ledtemp()  # Display temperature on LED Shim
    ledpress() # Display pressure on LED Shim
    
    text = time.strftime("It's %A %B %-d %-I:%M:%p")
    r, g, b = [0, 255, 255]
    
    if w == 1:
        r, g, b = [255, 255, 255]    
    
    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))
    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)

    if S == 0:
        unicornhathd.clear()
        unicornhathd.show()
        ledshim.clear()
        ledshim.show()
        os.system("sudo shutdown now -P")
        time.sleep(30)    
    
    if sensor.get_sensor_data(): 
        t = sensor.data.temperature 
        t = round(t)
          
    if t < -15:
        r, g, b = [255, 255, 255]# White
        text = ("and it's a Very Cold %sc") % (t)
    elif t <= 0 and t >= -15: 
        r, g, b = [0, 0, 255]    # Blue
        text = ("and it's a Cold %sc") % (t)
    elif t > 0 and t < 13:
        r, g, b, = [255, 255, 0] # Yellow
        text = ("and it's a cool %sc") % (t)
    elif t >= 13 and t < 25:
        r, g, b = [0, 255, 0]    # Green
        text = ("and it's %sc") % (t)
    elif t >= 25 and t < 30:
        r, g, b = [255, 140, 0]  # Orange
        text = ("and it's a Hot %sc") % (t)
    elif t >= 30:
        r, g, b = [255, 0, 0]    # Red
        text = ("and it's a Very Hot %sc") % (t)

    if w == 1:
        r, g, b = [255, 255, 255]
        
    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))
    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)

    if S == 0:
        unicornhathd.clear()
        unicornhathd.show()
        ledshim.clear()
        ledshim.show()
        os.system("sudo shutdown now -P")
        time.sleep(30)
        
    if sensor.get_sensor_data():
        h = sensor.data.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)

    if w == 1:
        r, g, b = [255, 255, 255]

    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))
    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)
        
    if S == 0:
        unicornhathd.clear()
        unicornhathd.show()
        ledshim.clear()
        ledshim.show()
        os.system("sudo shutdown now -P")
        time.sleep(30)    
    
    if sensor.get_sensor_data(): 
        p = sensor.data.pressure 
        p = round(p)
            
    if p > 0 and p < 982:             # Very Low
        r, g, b = [255, 0, 0]         # Red
        text = ("and the Pressure is a Very Low %smb : Storm Watch") % (p)
    elif p >= 982 and p < 1004:       # Low
        r, g, b = [255, 255, 0]       # Yellow
        text = ("and the Pressure is a Low %smb : Posible Precipitation") % (p)
    elif p >= 1004 and p < 1026:      # Mid Range
        r, g, b = [0, 255, 0]         # Green
        text = ("and the Pressure is %smb") % (p)
    elif p >= 1026 and p < 1048:      # High
        r, g, b = [0, 0, 255]         # Blue
        text = ("and the Pressure is a High %smb") % (p)
    elif p >= 1048:                   # Very High
        r, g, b = [255, 50, 0]        # Orange
        text = ("and the Pressure is a Very High %smb") % (p)

    if w == 1:
        r, g, b = [255, 255, 255]

    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))
    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)
        
    if S == 0:
        unicornhathd.clear()
        unicornhathd.show()
        ledshim.clear()
        ledshim.show()
        os.system("sudo shutdown now -P")
        time.sleep(30)    
    
    uva, uvb = uv_sensor.get_measurements()
    uv_comp1, uv_comp2 = uv_sensor.get_comparitor_readings()
    uv_indices = uv_sensor.convert_to_index(uva, uvb, uv_comp1, uv_comp2)

    uv =('{0[2]}'.format(uv_indices)) #uv reading as a float value with no text mixed in
    u = int(float(uv)) #uv index converted to an integer value
    u = round(u)

    if u > 0 and u < 3:     # Low
        r, g, b = (0, 255, 0)    # Green 
        text = ("UV Index is Low @ %s") % (u)
    elif u >= 3 and u < 6:  # Moderate
        r, g, b = (255, 255, 0)  # Yellow
        text = ("UV Index is Moderate @ %s") % (u)
    elif u >= 6 and u < 8:  # High
        r, g, b = (255, 140, 0)    # Orange 
        text = ("UV Index is High @ %s") % (u)
    elif u >= 8 and u < 11: # Very High
        r, g, b = (255, 0 ,0)    # Red
        text = ("UV Index is Very High @ %s") % (u)
    elif u >= 11:           # Extreme
        r, g, b = (255, 0, 255)  # Violet
        text = ("UV Index is Extreme @ %s") % (u)

    if w == 1:
        r, g, b = [255, 255, 255]

    if u > 0:

        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))
        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)
            
# Last edited on Dec 13 2020
# new code for Unicorn Hat HD
# curl https://get.pimoroni.com/bme680 | bash
# curl https://get.pimoroni.com/ledshim | bash
# sudo pip3 install ltr559
# sudo pip3 install veml6075
# run crontab -e
# add
# @reboot python3 /home/pi/HD_Port_WC.py &

Wow! Thanks so much for sharing this! I’m gonna pick it apart and learn.

All my Pi stuff is here, it’s my Public Onedrive folder.

This is the file you likely should be looking at. It was in the Blinkt folder.

#!/usr/bin/env python

import os
import time
import RPi.GPIO as GPIO
import psutil
import blinkt

from sys import exit

GPIO.setmode(GPIO.BCM)  
GPIO.setwarnings(False)
GPIO.setup(17, GPIO.IN, pull_up_down = GPIO.PUD_UP)  

x = 2

blinkt.set_clear_on_exit()

def Shutdown(channel):  
    global x
    x = 0

def show_graph(v, r, g, b):

    v *= blinkt.NUM_PIXELS

    for x in range(blinkt.NUM_PIXELS):

        if v < 0:

            r, g, b = 0, 0, 0

        else:

            r, g, b = [int(min(v, 1.0) * c) for c in [r, g, b]]

        blinkt.set_pixel(x, r, g, b)

        v -= 1

    blinkt.show()

blinkt.set_brightness(0.1)

GPIO.add_event_detect(17, GPIO.FALLING, callback = Shutdown, bouncetime = 2000)

while True:

    v = psutil.cpu_percent() / 100.0

    show_graph(v, 0, 0, 255)

    time.sleep(0.01)
    
    if x == (0):
        blinkt.set_all(0, 0, 0)
        blinkt.show()
        os.system("sudo shutdown now -P")
        time.sleep(30)

# run sudo crontab -e
# add
# @reboot python3 /home/pi/cpu_load.py &     

Amazing! Thank you SO much! Is there any way I can buy you a beer or a cup of coffee? This is tremendously helpful!

I’m good, thanks for the offer though. I’m sipping on a rum & coke yar as I type this. =)
I forgot I had that file, its a modified version of the cpu_load example file.
I did a similar edit of the cpu_temp example.

It’s kind of ironic and funny in that all I use my “Microsoft” OneDrive folder for is too share my Raspberry Pi, Pi PICO, Arduino, and BBC MicroBit stuff. =)
Your welcome to reuse anything in there. A lot of it started out as Pimoroni examples that I changed and added too. Or stuff I found on the Internet.

1 Like

Sigh. Sorry, it’s me again. I’m using your startup script (modified, of course) and it’s just not working. I took out all of the graphing stuff and so forth, trying to leave in just the stuff about shutting down and Blinkt. But when I shut down – either through my button or through sudo shutdown – the lights stay on.

I’ve taken enough of your time already, but if you have a moment to look at this…

import os
import time
import RPi.GPIO as GPIO
import blinkt

from sys import exit

GPIO.setmode(GPIO.BCM)  
GPIO.setwarnings(False)
GPIO.setup(3, GPIO.IN, pull_up_down = GPIO.PUD_UP)  

x = 2

blinkt.set_clear_on_exit()

def Shutdown(channel):  
    global x
    x = 0


GPIO.add_event_detect(3, GPIO.FALLING, callback = Shutdown, bouncetime = 2000)

while True:
    
    if x == (0):
        blinkt.set_all(0, 0, 0)
        blinkt.show()
        os.system("sudo shutdown now -P")
        time.sleep(30)

I changed the GPIO reference to 3, since that’s the pin I’m using for my shutdown button. Other than that… I don’t get it. It should work, right?

Yes it “should” work. Keep in mind though that GPIO 3 is used for i2c, and has internal pullups. If i2c isn’t being used make sure its turned off in The Raspberry Pi configuration menu.
Does the Blinkt clear?
Does it shutdown?

i2c is definitely turned off in raspi-config.

The Pi turns off, but the Blinkt doesn’t clear.

ETA: I think I got it working. I put the below code into a file in /lib/systemd/system-shutdown and it seems to be working.

import blinkt
import os
import time

os.popen ("kill $(pgrep -f rainbow.py)")
time.sleep (2.0)
blinkt.clear()
blinkt.show()

If you have another file running that is lighting up the blinkt its not going to clear. Thats why I added it to the file I’m running, all in the one file.