Hello
using python-function i'm not able to get get the variable value
import sys
sys.path.append("/home/pi/.local/lib/python3.9/site-packages")
from pigpio_encoder.rotary import Rotary
import threading
import time
global my_counter
my_counter = 0
def sw_short():
pass
def up_callback(counter):
global my_counter
if counter%40==0:
my_counter+=1
msg['payload'] = {'pos_x':my_counter}
print(msg)
#print(my_counter)
def down_callback(counter):
global my_counter
if counter%40==0:
my_counter-=1
msg['payload'] = {'pos_x':my_counter}
return msg
#return my_counter
#print(my_counter)
def pippo():
global my_counter
print(my_counter)
time.sleep(0.3)
pippo()
my_rotary = Rotary(clk_gpio=13, dt_gpio=12,sw_gpio = 17)
my_rotary.setup_rotary( min=-1000000,
max=1000000,
debounce = 1,
up_callback=up_callback,
down_callback=down_callback,)
#rotary_callback=rotary_callback,
my_rotary.setup_switch(sw_short_callback=sw_short)
return msg
This is the code, i'm not able to desplay the value of my_counter
[
{
"id": "f23f10101329d95f",
"type": "python-function",
"z": "a2713db36e62f1e7",
"name": "Encoder",
"func": "import sys\nsys.path.append(\"/home/pi/.local/lib/python3.9/site-packages\")\nfrom pigpio_encoder.rotary import Rotary\nimport threading\nimport time\nglobal my_counter\nmy_counter = 0\n\ndef sw_short():\n pass\n\ndef up_callback(counter):\n global my_counter\n if counter%40==0:\n my_counter+=1\n msg['payload'] = {'pos_x':my_counter}\n print(msg)\n #print(my_counter)\n\ndef down_callback(counter):\n global my_counter\n if counter%40==0:\n my_counter-=1\n msg['payload'] = {'pos_x':my_counter}\n return msg\n #return my_counter\n #print(my_counter)\n \ndef pippo():\n global my_counter\n print(my_counter)\n time.sleep(0.3)\n pippo()\n\n\nmy_rotary = Rotary(clk_gpio=13, dt_gpio=12,sw_gpio = 17)\nmy_rotary.setup_rotary( min=-1000000,\n max=1000000,\n debounce = 1,\n up_callback=up_callback,\n down_callback=down_callback,)\n #rotary_callback=rotary_callback,\nmy_rotary.setup_switch(sw_short_callback=sw_short)\nreturn msg\n# x = threading.Thread(target=pippo)\n# x.start()\n\n",
"outputs": 1,
"x": 220,
"y": 100,
"wires": [
[
"393990a61c77173e"
]
]
}
]
edje11
19 January 2023 19:29
2
Hard to test without the required hardware.
Function throws at least some error's so there's is happening something
Strip your code and see where it's going wrong.
If you installed node-red via the script, it gave you an option to install Pi specific nodes, one of which are the GPIO nodes if I am not mistaken, you can install them separately too. No need for external python scripts if you can do it all inside node-red.
i get no error, simply i never get the msg
i will try but i don't understand why if i run the script outside node-red i get the needed value, inside node-red i'm not able to get the needed value in the msg objects
when you run python are you using the -u
parameter to ensure it flushes any results to the output ?
no i never put the -u, where i have to put it ?
this is what i see when i run the flow but i have no output
Ah sorry didn’t spot you were using a custom node. I usually just call python -u from an exec node
Colin
20 January 2023 22:15
9
I remember that others have had problems using that node, as Dave suggests, you might be better using an exec node to call your script. If you do that make sure you put the full path to the script in the exec node.
Hello
Now i'm in this situation but no output:
inject
exec
Debug
Python code
import RPi.GPIO as GPIO
from time import sleep
counter = 10
Enc_A = 13
Enc_B = 12
def init():
print("Rotary Encoder Test Program")
GPIO.setwarnings(True)
GPIO.setmode(GPIO.BCM)
GPIO.setup(Enc_A, GPIO.IN)
GPIO.setup(Enc_B, GPIO.IN)
GPIO.add_event_detect(Enc_A, GPIO.RISING, callback=rotation_decode, bouncetime=10)
return
def rotation_decode(Enc_A):
global counter
sleep(0.002)
Switch_A = GPIO.input(Enc_A)
Switch_B = GPIO.input(Enc_B)
if (Switch_A == 1) and (Switch_B == 0):
counter += 1
print("direction -> ", counter)
while Switch_B == 0:
Switch_B = GPIO.input(Enc_B)
while Switch_B == 1:
Switch_B = GPIO.input(Enc_B)
return
elif (Switch_A == 1) and (Switch_B == 1):
counter -= 1
print("direction <- ", counter)
while Switch_A == 1:
Switch_A = GPIO.input(Enc_A)
return
else:
return
def main():
try:
init()
while(True) :
sleep(1)
except KeyboardInterrupt:
GPIO.cleanup()
if __name__ == '__main__':
main()
I really don't know why i never see any value in the debug.
Colin
23 January 2023 21:14
11
Check all outputs of the exec node, set the debug nodes to show the full message.
Add some debug output to your script to see what is happening and what is not happening.
hello i start from easy test just for understand the problem
if i do so:
as you can see in the debug i have the return value
but how can do if the return value is inside a def
for example:
def test()
msg = 'test'
return test
while True:
test()
it run but i don't have any return value
i have solved this issue doing this:
global pippo
def test():
global pippo
pippo = 'test'
return pippo
while True:
test()
msg['payload'] = {'pippo':pippo}
return msg
but i don't understand why in node-red i have the msg one time and not repeated.
But my big problem is this:
from pigpio_encoder.rotary import Rotary
global my_counter
my_counter = 0
def sw_short():
pass
def up_callback(counter):
global my_counter
if counter%40==0:
my_counter+=1
print(my_counter)
return my_counter
def down_callback(counter):
global my_counter
if counter%40==0:
my_counter-=1
print(my_counter)
return my_counter
my_rotary = Rotary(clk_gpio=13, dt_gpio=12,sw_gpio = 17)
my_rotary.setup_rotary( min=-10000,
max=10000,
debounce = 1,
up_callback=up_callback,
down_callback=down_callback,)
#rotary_callback=rotary_callback,
my_rotary.setup_switch(sw_short_callback=sw_short)
msg['payload'] = {'my_counter':my_counter}
return msg
Always return
it return my_counter = 0 because he get the value from the beginning but not when the value change
can you tell me where is my mistake
Thanks
I am not at home in python, but aren't variables global by default if they are defined outside a function ? ie. can you remove all the "global" definitions ?
sorry guys but i really don't understand:
from pigpio_encoder.rotary import Rotary
global my_counter
my_counter = 0
def sw_short():
pass
def up_callback(counter):
global my_counter
if counter%40==0:
my_counter+=1
print(my_counter)
msg['payload'] = {'my_counter':my_counter}
return msg
def down_callback(counter):
global my_counter
if counter%40==0:
my_counter-=1
print(my_counter)
msg['payload'] = {'my_counter':my_counter}
return msg
my_rotary = Rotary(clk_gpio=13, dt_gpio=12,sw_gpio = 17)
my_rotary.setup_rotary( min=-10000,
max=10000,
debounce = 1,
up_callback=up_callback,
down_callback=down_callback,)
#rotary_callback=rotary_callback,
my_rotary.setup_switch(sw_short_callback=sw_short)
msg['payload'] = {'my_counter':my_counter}
return msg
i get only the first msg object with my_counter = 0
then when i move the encoder in the node-red shell i get all the print message :
but i get no return object.
dear bakman2 in node-red if i never set as global the my_counter variable i get:
NameError: name 'my_counter' is not defined
Any help will be appreciated
Your script does the following:
set your counter variable to the value of 0
create an instance of Rotary and set a few properties of it
set your msg['payload'] to a value
return this msg
After the return command the script is terminated because there are no more commands. Therefore you get once the value of msg.
The two function (the callback functions for the Roraty object) will never have been called, because the script is finished before the Rotary object can fire any event.
I have solved in this way :
from pigpio_encoder.rotary import Rotary
global my_counter
my_counter = 0
def sw_short():
pass
def up_callback(counter):
global my_counter
if counter%40==0:
my_counter+=1
#print(my_counter)
msg['payload'] = {'my_counter':my_counter}
#return msg
node.send(msg)
def down_callback(counter):
global my_counter
if counter%40==0:
my_counter-=1
#print(my_counter)
msg['payload'] = {'my_counter':my_counter}
node.send(msg)
my_rotary = Rotary(clk_gpio=13, dt_gpio=12,sw_gpio = 17)
my_rotary.setup_rotary( min=-10000,
max=10000,
debounce = 1,
up_callback=up_callback,
down_callback=down_callback,)
#rotary_callback=rotary_callback,
my_rotary.setup_switch(sw_short_callback=sw_short)
#msg['payload'] = {'my_counter':my_counter}
#return msg
Regards
Hello Oliver
the lib used pigpio do in backgroud the work (treading etc...) but i have solved usin the nod.sed(msg)
regards
Okay, I see.
BTW: your problem was the fact, that callback functions cannot return anything by definition. So your solution is the right way.
Just linking in case you find this easier
More compact version using a function node
[image]
[{"id":"2c40d42d.176cbc","type":"debug","z":"dfaf687e.30fb88","name":"STATUS_FUNCTION","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":680,"y":540,"wires":[]},{"id":"e2775f3d.af2bd","type":"change","z":"dfaf687e.30fb88","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"CLK","tot":"str"}],"action":"","property":"","from":"","to":"","re…
1 Like