A way to detect button press?

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
misaalanshori
Posts: 27
Joined: Sat Jun 22, 2019 6:07 am

A way to detect button press?

Post by misaalanshori » Tue Nov 12, 2019 11:25 am

Currently i have this code, but Im getting "NameError: local variable referenced before assignment" from line 6 about the "lastState" variable even though I already created the variable with value 0 before I call the function

Code: Select all

from machine import Pin
button = Pin(0, Pin.IN)
lastState = 0 #Variable created here
def buttonPress():
    tempState = button.value()
    if (lastState == 0) and (tempState == 1): #Error on this line
        lastState = tempState
        return 1
    elif (lastState == 1) and (tempState == 1):
        lastState = tempState
        return 2
    elif (lastState == 1) and (tempState == 0):
        lastState = tempState
        return 3
    else:
        return 0

while True:
    print(buttonPress())
It's supposed to return 1 if the button is pressed (state change from 0 to 1), and then return 2 (state change from 1 to 1) if its still pressed and then return 3 (state change from 1 to 0) if its stopped being pressed.
Can someone help me with the error? Also tell me if there is a better way to do this

misaalanshori
Posts: 27
Joined: Sat Jun 22, 2019 6:07 am

Re: A way to detect button press?

Post by misaalanshori » Tue Nov 12, 2019 12:53 pm

its been like 1 hour since i have this problem and I still can't seem to figure it out. It feel like its such a simple mistake but i just can't solve it. I even made another file and created a simple function that uses a variable from outside of the function and it works perfectly...

misaalanshori
Posts: 27
Joined: Sat Jun 22, 2019 6:07 am

Re: A way to detect button press?

Post by misaalanshori » Tue Nov 12, 2019 1:09 pm

This Code works (i had to invert the 1 and 0 but that shouldnt be the cause):

Code: Select all

from machine import Pin
import time
button = Pin(0, Pin.IN)

def buttonPress(num):
    temp = num
    if (temp == 1) & (button.value() == 0):
        return 1
    elif (temp == 0) & (button.value() == 0):
        return 2
    elif (temp == 0) & (button.value() == 1):
        return 3
    else:
        return 0
lastState = 0
while True:
    print(buttonPress(lastState))
    lastState = button.value()
    print("                  " + str(button.value()))
    time.sleep_ms(50)
but it doensnt look as good, where is the problem here...

User avatar
jimmo
Posts: 2754
Joined: Tue Aug 08, 2017 1:57 am
Location: Sydney, Australia
Contact:

Re: A way to detect button press?

Post by jimmo » Tue Nov 12, 2019 1:09 pm

In Python, you need to explicitly tell it that you're assigning to a global variable.

The problem here is that (later in the function) you assign to lastState, which means that Python thinks that lastState is a function local variable. So on line six, the "read" of localState tries to get the local variable, which doesn't exist yet.

Adding a line at the top of the function:

Code: Select all

def buttonPress():
  global localState
will fix this.

Here's more info from the Python FAQ -- https://docs.python.org/3/faq/programmi ... -in-python

misaalanshori
Posts: 27
Joined: Sat Jun 22, 2019 6:07 am

Re: A way to detect button press?

Post by misaalanshori » Tue Nov 12, 2019 1:13 pm

Ohh, thanks for the explanation!! this has confused me for way too long, I just expected it to just be able to modify a global variable because I can read it so why couldn't I modify it...

misaalanshori
Posts: 27
Joined: Sat Jun 22, 2019 6:07 am

Re: A way to detect button press?

Post by misaalanshori » Tue Nov 12, 2019 1:16 pm

Thank you so much, everything works as expected now!

ploist13
Posts: 1
Joined: Sat Nov 23, 2019 7:52 pm

Re: A way to detect button press?

Post by ploist13 » Sat Nov 23, 2019 7:57 pm

I had the same problem, and now it's work thank u!

Post Reply