3

Following the RPI Education Manual

I am trying to check if the button has been pressed in a separate thread so i can continue the rest of my program, I have followed the Manual exactly but I must have missed something as I keep getting the error

    Traceback (most recent call last):
    File "/home/pi/btnThreading2.py", line 8, in <module>
    class Button(threading.Thread):
    File "/home/pi/btnThreading2.py", line 36, in Button
    button = Button(36)
    NameError: name 'Button' is not defined

What did i do wrong?

import threading
import time
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BOARD)


class Button(threading.Thread):

    def __init__(self, channel):
            threading.Thread.__init__(self)
            self._pressed = False
            self.channel = channel
            GPIO.setup(self.channel, GPIO.IN)
            self.deamon = True
            self.start()

    def run(self):
            previous = None
            while 1:
                    current = GPIO.input(self.channel)
                    time.sleep(0.01)

                    if current is False and previous is True:
                            self._pressed = True

                            while self._pressed:
                                    time.sleep(0.05)

                    previous = current

    def onButtonPress():

            print("btn presdsed")

    button = Button(36)

    while True:
            name = input('Enter a Name:')
            if name.upper() == ('Q'):
                    break
            print('hello', name)

            if button.pressed():
                    onButtonPress()
  • 3
    The RPI Foundation seriously produced a document which encourages people to write background busy loops to watch for button presses?!??! And slapped "education" and "for schools" on it? I'm so appalled I want to start a letter writing campaign. It is just bad programming -- a problem they claim solving was a motivation for the pi in the first place, but I suspect they have only made the situation worse. Anyway, this is tangential and obviously doesn't solve your program. – goldilocks Feb 19 '16 at 2:33
  • Though this code may be running on an RPi, this question is not RPi specific. I suggest you look/ask on stackoverflow.com, another Stack Exchange site that is very good. – Patrick Cook Feb 19 '16 at 3:36
  • 1
    @goldilocks: Let's just say that manual the OP referenced leaves a lot to be desired. – Jacobm001 Feb 19 '16 at 4:29
  • 1
    @PatrickCook: It may not be Raspberry Pi specific, but the code does come from the RPi Foundation's materials... For that reason I voted to leave the question open. – Jacobm001 Feb 19 '16 at 4:38
  • @Jacobm001 Can't argue with that. StackOverflow is still a great place to go with Python questions though. – Patrick Cook Feb 19 '16 at 4:41
7

You're getting an error because your code doesn't make sense. Unlike C, C++, or Java, Python has no parentheses. Rather, it uses indentation to determine logical blocks. Since you never "deindent" at the end of your class, Python is interpreting everything after class Button(threading.Thread): as a part of the class.

Additionally, your code is inconsistently formatted. The first time you indent, you use 4 spaces. Everywhere else, you use 8. This will make Python unhappy. You can use whatever indentation value you want (I suggest tabs instead of spaces), but you need to be consistent.

You need to deindent lines 36-45 and then delete the empty lines 9 and 35. That gives you the code:

import threading
import time
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BOARD)

class Button(threading.Thread):
    def __init__(self, channel):
        threading.Thread.__init__(self)
        self._pressed = False
        self.channel = channel
        GPIO.setup(self.channel, GPIO.IN)
        self.deamon = True
        self.start()

    def run(self):
        previous = None
        while 1:
            current = GPIO.input(self.channel)
            time.sleep(0.01)

            if current is False and previous is True:
                self._pressed = True

                while self._pressed:
                    time.sleep(0.05)

            previous = current

    def onButtonPress():
        print("btn presdsed")

button = Button(36)

while True:
    name = input('Enter a Name:')

    if name.upper() == ('Q'):
        break
    print('hello', name)

    if button.pressed():
        onButtonPress()
  • Thank you! still getting used to python white spacing, i was afraid it would be something simple like that. – S.Rose Feb 21 '16 at 22:47
  • @S.Rose: No problem, we all have to learn from somewhere. I'm rather disappointed in the RPi foundation for not hosting source code samples for direct download with the manual. :( – Jacobm001 Feb 22 '16 at 3:40
  • It would make this much easier if they did host code samples to eliminate my white spacing errors. – S.Rose Feb 22 '16 at 3:44
  • Can't edit since it's less than 6 characters; the def onButtonPress() should be de-indented too. – Cameron Gagnon Sep 29 '16 at 18:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.