I use a Raspberry Pi Pico W to control a LED Strip. On the main thread I do all the networking. On the other thread I´m trying to rotate the LED´s in a given interval. However, if I want to change this interval, I have to terminate the thread and create a new thread.
To archive this, I have defined a variable rotate_isAlive, that I want to set to False in order to terminate thread 2 to setup a new one. I use the global keyword for this. This is in my main loop:
global rotate_isAlive
...
if (rotate_isAlive):
rotate_isAlive = False
if rotation_direction == "right":
# rotate right
rotate_isAlive = True
_thread.start_new_thread(do_rotate_r, (d,ltr)
else:
# rotate left
rotate_isAlive = True
_thread.start_new_thread(do_rotate_l, (d,ltr)
And this is in thread 2:
def do_rotate_l(delay, num_led_to_rotate):
while True:
if rotate_isAlive == False:
_thread.exit()
break
pixels.rotate_left(num_led_to_rotate)
pixels.show()
time.sleep(delay/1000)
I followed this guide that suggests the given use of global variables, however my implementation doesn't work: https://www.youtube.com/watch?v=1q0EaTkztIs
CodePudding user response:
Turning what @user2357112 said into a full-on answer:
The very next thing that your main thread does after it sets rotate_isAlive=False
is, it sets it back to True
again.
if rotate_isAlive:
if rotate_isAlive = False
if rotation_direction == "right":
rotate_isAlive = True
...
else:
rotate_isAlive = True
...
Meanwhile, the do_rotate
thread spends most of its time sleeping. The chance of it fetching rotate_isAlive
during the fraction of a microsecond when rotate_isAlive==False
is nearly zero.
You need to wait for the do_rotate
thread to acknowledge that it saw the flag change. Since it reacts to the flag by dying, you can wait by join
ing it:
if rotate_isAlive:
if rotate_isAlive = False
do_rotate_thread.join()
...
But wait! user2357112 suggested a much better way to solve your problem: Don't kill the thread. Change it's "marching orders."
global g_delay
global g_num_led_to_rotate
global g_rotation_direction
...
g_delay = ...whatever...
g_num_led_to_rotate = ...whatever...
if rotation_direction == "right":
g_rotation_function = DIR_RIGHT
else:
g_rotation_function = DIR_LEFT
And in the do_rotate
thread:
while True:
if g_rotation_direction = DIR_RIGHT:
pixels.rotate_right(g_num_led_to_rotate)
else:
pixels.rotate_left(g_num_led_to_rotate)
pixels.show()
time.sleep(g_delay/1000)