How to implement "software interrupt"? - python

I am trying to create an "emergency stop" button that will immediately stop / break a linear code execution, but I am unable to come up with a solution. We have a GUI running in a browser and when a button is pushed an MQTT messages is received by the back end (which is written by me in Python).
There are different threads and the message is received, but when in another thread an if statement is running I am unable to figure out how to stop / break the linear code execution in that thread right away. Is there a good method for this?
It would be also OK if I could stop the entire thread and afterwards start it again (if another button is pushed). How could I do that?
I mean. I could probably solve this right away if I would be using a hardware switch and an interrupt (the code is running on a Raspberry Pi by the way). But I do not know how to "simulate" an interrupt and an interrupt service routing in a software. I most definitely can't be the only person facing the same problem.

Related

Stuck in a loop - Threaded continues while loop prevents code from moving forward (Python)

EDIT:
I apparantly wasn't aware of daemon threads.. This solved the main issue..
Now just puzzling to keep the loop checking for button press, whether it has been pressed or not =)
I'm trying to stop a raspberry pi running code when I press a button (emergency stop button connected to the pins).
So far it's not working out. (In my example code I use code to switch the light of the button to make testing easier).
The threading seems to be working well, however the shell program installed in the pi running the code, first 'test runs' the code to check for errors before actually executing. In my while not read_button() code, the 'checking' of the code gets stuck on the 'while not' until I press the button; not ideal..
Reversing the code and having while read_button() or only if read_button() doesn't actually respond to my button press, since likely the code finishes after checking instead of continuously check.
So.. How to solve this? A continues loop stops my code from proceeding until the while loop is broken (I did join the thread in the end..). A non-continues loop doesn't function, since it won't continuously check for the button press..
To make things worse; after the emergency stop was performed I want the thread to still continue checking for button press after (the user might decide to resume the program and have to hit emergency stop again later on the way within the same code).
I feel like I'm in an endless loop myself trying to fix this =P
(Sorry for the lengthy post and sorry for any noob-terms used, I'm very new to this; only picked programming up 3 weeks ago)
Thank you very much in advance!!
def button_check():
while not read_button(): #developer API
if read_button():
set_button_light(blue=True) #developer API
t = Thread(target=button_check)
t.start()
time.sleep(20) #just to give me time to test
t.join()

How can I handle Pepper robot shutdown event?

I need to handle the event when the shutdown process is started(for example with long press the robot's chest button or when the battery is critically low). The problem is that I didn't find a way to handle the shutdown/poweroff event. Do you have any idea how this can be done in some convenient way?
Unfortunately this won't be possible as when you trigger a shutdown naoqi will exit as well and destroy your service.
If you are coding in c++ you could use a destructor, but there is no proper equivalent for python...
An alternative would be to execute some code when your script exits whatever the reason. For this you can start your script as a service and wait for "the end" using qiApplication.run(). This method will simply block until naoqi asks your service to exit.
Note: in case of shutdown, all services are being killed, so you cannot run any command from the robot API (as they are probably not available anymore!)

wxPython & Pyserial - Continuous communication

I am a newbie to python and I am learning new things day by day. I have a question regarding integrating wxpython and pyserial. I am writing a GUI application to control a microprocessor through pyserial.
I have a wxpython script written - displays good - with buttons and text fields.
I tested communication with my microprocessor using small commands from pyserial - everything is in good place.
Problem:
I will be having a button (say Button A) on my GUI, which after clicked - checks if the serial communication is made (by sending and receiving data ofcourse). Once the communication is good, I have to make sure the communication stays good as long as I am using my GUI. So I decided to write an external function which continuously sends and reads data (probably a for loop). Based on the functions return value I will know if my serial communication is active or not (this might be a bad idea - but thats the best I got)
Now the problem is I have a lot of other features on my GUI, buttons, text fields etc.. So for example when another button (say button B) is pressed I want to send a specific command to the microprocessor. This requires I interrupt the serial communication which was going on in my Step 1, send data from button B click, then re-start the Step 1 communication again (to keep checking my serial communication is active). I dont know how I can interrupt the communication. The Step 1 serial communication (for loop) is bound to the Button A click. Once the Button A is clicked, it goes to a for loop and serial communication is checked continuously.
I have so many buttons and text fields like this - which are going to read and write data to the Microprocessor. Whenever I want to do an event, I have to stop the serial communication in step 1 and restart it again.
On top of all this, I can only check the serial communication (mentioned in Step 1) every 100ms. I cannot just write a for loop. I have to do some modifications - like time.delay(100ms) or something.
I dont know how to frame it, but may be I just require a good algorithm idea or implement this somehow with help of import sched or import thread
I am trying majorly to avoid import thread - because my microprocessor has very minimal RAM. Also using threading with wxPython is pain in the neck (what I read online)
One of my colleagues suggested using "timer service" from my Operating system. I dont think python have a feature like that. I have no clue what he is talking about, at the least. His argument is that, if I can use this, I can run the continuous serial communication check every 100ms very easily.
Any help would be greatly appreciated. I am not looking for any complicated solutions, I appreciate if you attach a piece of code, use very basic programming. I have the wxPython GUI in a single class.

Use interrupts with python with Raspberry Pi B+

I have a little problem here I hope you can help me.
I need to interrupt the main thread of my program but I don't want to run a new thread. I just want to when I press a button cause an interruption of the main thread.
I have read this post http://raspi.tv/2013/how-to-use-interru ... pio-part-3 but neither of the options that mention there works for me.
I've also read something about using wiringpi2 library, precisely the function wiringPiISR. But every time I execute my code, no matter if the button is pressed or not, the function my_callback executes anyway.
wpi = wiringpi2.GPIO(wiringpi2.GPIO.WPI_MODE_PINS)
wpi.pullUpDnControl(2,wpi.PUD_UP)
wpi.wiringPiISR(2, wpi.INT_EDGE_RISING, my_callback())
Thank you very much

Detecting computer/program shutdown in Python?

I have a Python script that runs in a loop regularly making adjustments to my lighting system. When I shut down my computer, I'd like my script to detect that, and turn off the lights altogether.
How do I detect my computer beginning to shut down in Python?
Or, assuming Windows sends Python a "time to shut down" notice, how do I intercept that to kill my lights and exit the loop?
This is the wrong way to go about performing action at system shutdown time. The job of the shutdown process is to stop running processes and then switch off power; if you try to detect this happening from within your program and react by getting some last action in, it's a race between the OS and your program who gets to go first. More likely than not your program will have been stopped before it managed to perform the necessary action.
Instead, you should hook into the normal protocol for doing things at shutdown. This will tell the shutdown utility to send an explicit signal to your program and wait for it to be acknowledged, which gives you enough time (within reason) to do what you have to do. How exactly to register to be notified varies with the OS, so this is more of an OS-specific question rather than a Python question.
You should react to the WM_ENDSESSION message.
This message is sent when the user logs off or the computer gets shut down.
If you want to react to Sleep/Hibernate as well, you'll need to handle WM_POWERBROADCAST with PBT_APMSUSPEND.
But I don't know how to do that in python. I guess it depends on your windowing framework since you need have a windows/a message loop to receive messages.

Categories