0

I'm setting up my Christmas village early so I can make changes to it this year. I'm trying to get an LED strip and a string of LED lights to fade at varying speeds at the same time. the code works for a minute then gives me an "int not subscriptable" error.

I've been looking at examples that have caused this error for others but I'm not figuring out why my code is doing it.

# imports
import RPi.GPIO as GPIO
import time
from threading import Thread
import random

# global values

GPIO.setmode(GPIO.BOARD)
led = [31, 37, 35, 33]
village = [36, 38, 40]
# generate array for led brightness
ledV = [0, 0, 0, 100]
ledFV = [random.randint(1, 3), random.randint(1, 3), random.randint(1, 3), 0]
ledDelay = [0.03, 0.4, 0.2, 0]
# always gives GPIO in use even when not this mutes that
GPIO.setwarnings(False)
tmpLoop = 10

def setup():
    # using GPIO.BOARD makes it so you can
    # count the pins and use that number
    # 1-2
    # 3-4 etc...
    # set led pins to output
    GPIO.setup(led[0], GPIO.OUT)
    GPIO.setup(led[1], GPIO.OUT)
    GPIO.setup(led[2], GPIO.OUT)
    GPIO.setup(led[3], GPIO.OUT)
    # setup PWM for fading on any pin
    led[0] = GPIO.PWM(31, 100)
    led[1] = GPIO.PWM(37, 100)
    led[2] = GPIO.PWM(35, 100)

    led[0].start(0)
    led[1].start(0)
    led[2].start(0)

    # turn on LEDstrip 
    GPIO.output(led[3], 255)

def ledFader(pin, value):
    global ledV
    if ledV[pin] < value:
        while (ledV[pin] < value):
            # This is the spot that it says is causing the error                          
            ledV[pin] = ledV[pin] + ledFV[pin]
            if ledV[pin] > 100:
                ledV[pin] = 100
            led[pin].ChangeDutyCycle(ledV[pin])
            time.sleep(ledDelay[pin])
    if ledV[pin] > value:
        while (ledV[pin] > value):
            ledV[pin] = ledV[pin] - ledFV[pin]
            if ledV[pin] < 0:
                ledV = 0
            led[pin].ChangeDutyCycle(ledV[pin])
            time.sleep(ledDelay[pin])

def LEDThread():
    while True:
        ledFader(1, 100)  # no green
        ledFader(2, 100)  # no red
        ledFader(1, 0)  # green on
        ledFader(0, 100)  # no blue
        ledFader(2, 0)   # red on
        ledFader(1, 100)  # no green
        ledFader(0, 0)   # blue on
        ledFader(1, 0)   # green on
    GPIO.cleanup()

setup()
LEDThreadr = Thread(target=LEDThread())
LEDThreadr.start()

From what I can tell nothing should be going wrong. This is half the file. The other half is almost identical but set up for the LED lights for the village. That part doesn't error out. (ran both threads separately in terminals and the LED String thread worked fine. If needed I can provide the whole code. (sorry for the long post/lots of code)

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Jamie
  • 15
  • 4
  • 2
    Please show the full traceback. – Barmar Oct 11 '19 at 23:42
  • 2
    `target=LEDThread()` should be `target=LEDThread` with no parentheses. – Barmar Oct 11 '19 at 23:42
  • 1
    Does it really say `subscribable` or is it `subscriptable`? This is why it's best to copy and paste the error message. – Barmar Oct 11 '19 at 23:43
  • @Barmar It's probably this error - Error: 'int' object is not subscriptable – mindless-overflow Oct 11 '19 at 23:46
  • @mindless-overflow That's what I think, too, hence my question. – Barmar Oct 11 '19 at 23:47
  • 2
    `if ledV[pin] < 0: ledV = 0` Think about that for a second... – Karl Knechtel Oct 11 '19 at 23:55
  • BTW, the random numbers in `ledFV` are chosen once ahead of time, and the same numbers will be used every time through the loop in `ledFader`, every time you call it. Just making sure that's what you wanted.... – Karl Knechtel Oct 11 '19 at 23:58
  • I figured they would be selected only once. I just wanted it to be slightly different every time I ran it so it wouldn't be the same every time I ran it. Also I'm running my TV as the screen and it was late when I first ran into the problem. I think my brain might have auto completed it as subscribeable but it very well might have been subscriptable. – Jamie Oct 13 '19 at 19:20

1 Answers1

1

Change this:

if ledV[pin] < 0:
    ledV = 0

to this:

if ledV[pin] < 0:
    ledV[pin] = 0

The line ledV = 0 sets the entire list equal to 0, instead you want to change the value of ledV[pin] which is just an item in the list.

Update

You shouldn't call your function when passing it to the Thread class, instead simply pass the function object:

LEDThreadr = Thread(target=LEDThread)

If you need to add arguments, you can use args or kwargs:

LEDThreadr = Thread(target=LEDThread, args=(1,2,3), kwargs={'key1': 1,'key2': 2}))
Lord Elrond
  • 13,430
  • 7
  • 40
  • 80
  • OK. I kinda feel bad knowing that was my problem. Didn't realize I missed that. There is one other Issue I'm running into. When setting up the thread it starts the thread when declaring it. Is there a way to make it not do that? – Jamie Oct 13 '19 at 14:21
  • I know it's outside of the scope of the question but I was wondering if you have any idea why LED lights (not the LED strip this code manipulates) wouldn't fade with nearly identical code? – Jamie Oct 13 '19 at 17:59
  • @user1769896 Sorry, I don't really know anything about that ;-) – Lord Elrond Oct 13 '19 at 21:07