Another Python Pipe error


#1

Hey there,

I’m currently working on a project where I have to light up 10 BlinkStick Strips accordingly to 10 temperature values which get send via a serial communication to the Raspberry Pi 3. What doesn’t sound like a big deal at first is driving me nuts right now. I don’t know why but I constantly get the same error at different parts of the code. But this mostly happens during the first run of the program. As soon as the main loop once ran threw (less than 10% of the trials) and the color of a Strip is only changed occasionally the program gets way more stable but still crashes after some time (always when a color changes).

How you can see in the code below I tried the workaround with the 20ms delay after every color change but even a 50ms delay won’t do the job and with 80 LEDs a refresh would take over 4 seconds.

Is this a known bug with a solution?

Error message (seems to be typical python API error):

Traceback (most recent call last):
File "Raspberry_program.py", line 72, in <module> bstick.set_color(index=0, red=255, green=0, blue=0)
File "/usr/local/lib/python2.7/dist-packages/blinkstick/blinkstick.py", line 341, in set_color    lf._usb_ctrl_transfer(0x20, 0x9, report_id, 0, control_string)
File "/usr/local/lib/python2.7/dist-packages/blinkstick/blinkstick.py", line 244, in _usb_ctrl_transfer return self.device.ctrl_transfer(bmRequestType, bRequest, wValue, wIndex, data_or_wLength)
File "/usr/local/lib/python2.7/dist-packages/usb/core.py", line 711, in ctrl_transfer self.__get_timeout(timeout)
File "/usr/local/lib/python2.7/dist-packages/usb/backend/libusb1.py", line 836, in ctrl_transfer timeout))
File "/usr/local/lib/python2.7/dist-packages/usb/backend/libusb1.py", line 571, in _check raise USBError(_str_error[ret], ret, _libusb_errno[ret]) usb.core.USBError: [Errno 32] Pipe error

Heres my code (nothing too fancy but usually works just fine)

#!/usr/bin/python
from blinkstick import blinkstick
import time
import serial
ser = serial.Serial('/dev/ttyACM0', 115200)                     # enable the serial port
numreadings = 10
ledcount = 8
lowlim = 0
lowthr = 35
highthr = 50
highlim = 120
serialnr=["blank" , "BS100000-3.0" , "BS100001-3.0" , "BS100002-3.0" , "BS100003-3.0" , "BS100004-3.0" ,     "BS100005-3.0" , "BS100006-3.0" , "BS100007-3.0" , "BS100008-3.0" , "BS100009-3.0"]
state=["def"] * 11
oldstate=["def"] * 11
temps=[0] * 11
oldtemps=[0] * 11
const=[0] * 11
delay = 0.08
i = 1
    if i > 10: i = 1


    inputstring = ser.readline()                    # read the serial data sent by the UNO
    time.sleep(0.05)
    temps = inputstring.split(";")

    print inputstring
                                  
    if temps[0] == "32767" :

            temps= map(int , temps)

            while i <= numreadings:

                    if temps[i] < lowthr and  temps[i] > lowlim : state[i] = "green"
                    if temps[i] < highthr and  temps[i] > lowthr : state[i] = "orange"
                    if temps[i] < highlim and  temps[i] > highthr : state[i] = "red"
                    if temps[i] < lowlim or  temps[i] >= highlim : state[i] = "error"

                    if state[i] == "green" and abs(oldtemps[i]- temps[i]) < 3: const[i] += 1
                    else : const[i] = 0
                    if const[i] >= 300 : state[i] = "standby"
                           

                    oldtemps[i] = temps [i]

                    if oldstate[i] != state[i]:
                            bstick = blinkstick.find_by_serial(serialnr[i])
                            time.sleep(delay)

                            o = 0
                            while o < ledcount:
				print(0
                                    bstick.set_color(index=o, red=0, green=0, blue=0)
                                    time.sleep(delay)
                                    o += 1

                            if state[i] == "error" :

                                    bstick.set_color(index=0, red=255, green=0, blue=0)
                                    time.sleep(delay)

                            if state[i] == "standby" :

                                    bstick.set_color(index=0, red=0, green=10, blue=0)
                                    time.sleep(delay)

                            if state[i] == "green" :
                                    o = 0
                                    while o < ledcount:
                                            bstick.set_color(index=o, red=0, green=40, blue=0)
                                            time.sleep(delay)
                                            o += 1

                            if state[i] == "orange" :
                                    o = 0
                                    while o < ledcount:
                                            bstick.set_color(index=o, red=30, green=10, blue=0)
                                            time.sleep(delay)
                                            o += 1

                            if state[i] == "red" :
                                    o = 0
                                    while o < ledcount:
                                            bstick.set_color(index=o, red=30, green=0, blue=0)
                                            time.sleep(delay)
                                            o += 1

                            oldstate[i] = state[i]

                    print i
                    print temps[i]
                    print state[i]
                    i += 1

#2

How do you have those BlinkSticks connected to Pi?


#3

Via a 10 channel powered USB hub


#4

I just had an Idea: what if I change the mode of the BS Strip accordingly if I only want to set the color of one or all LEDs? From my understanding this would decrease the amount of packages sent to the BS via USB which therefore would minimize the risk of a failure.

Do you think this would be sufficient to give the program the required reliability?