We used raspberry pie to replace PLC and host computer in some industrial products, and introduced AI and machine vision into the industrial field with the help of the computing power of raspberry pie.
The previous products had no action mechanism, and only output the results to the indicator light, buzzer or display, without potential safety hazards,
Now the action mechanism is introduced, which needs to drive the equipment to perform certain actions according to the results. The introduction of the action mechanism increases the potential safety hazards of the product, such as hand clamping, machine collision, etc. Therefore, we need to design additional protection programs, the most important of which is the realization of emergency stop function.
- The emergency stop signal has the highest priority. In any case, pressing the emergency stop should stop immediately
- The action mechanism is powered by 24V, and the emergency stop switch is connected in series with the power supply. After the switch is pressed, the action mechanism will be powered off. (all emergency stop switches are equipped with locking mechanism, which will not pop up after being pressed and will remain pressed)
- Raspberry pie supplies power independently of the operating mechanism. After the emergency stop switch is pressed, raspberry pie receives the signal, starts to terminate the program, and then monitors the emergency stop button signal all the time.
- Python generally runs in a single thread. In order to respond to the emergency stop in time, the emergency stop function needs to be made into a main process, and the business action logic is used as a sub process. When the supervisor hears the emergency stop signal, the sub process is terminated immediately
- The reason for choosing a sub process instead of a sub thread is that Python sub threads cannot send a kill signal, and there is no good way to interfere with the behavior of sub threads (unless judged at each step, it will increase the code complexity), while sub processes can directly send a terminate signal to kill.
- The reason why the emergency stop is triggered by the low level is: we think that the low level is a stable state, and the high level is not a stable state. For example, if the power is cut off for some reason, the emergency stop should also be triggered. In case of any abnormal situation, it is always right to stop.
Python program flow chart
import RPi.GPIO as GPIO import time from multiprocessing import Process # Define signal pin button_stop = 20 button_reset = 21 button_start = 22 # Initialize GPIO def init_gpio(): GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) # Initialization buttons, which are triggered by low level GPIO.setup(button_reset, GPIO.IN) GPIO.setup(button_start, GPIO.IN) GPIO.setup(button_stop, GPIO.IN) # Business action def step_1(): time.sleep(3) return True def step_2(): time.sleep(3) return True def step_3(): time.sleep(3) return True # Reset action combination def run_reset(): move_reset_list = [ step_3, step_2, step_1 ] result = True try: for func in move_reset_list: func_name = func.__name__ print("Executing: %s" % func_name) func_result = func() if not func_result: result = False break except: result = False finally: if not result: exit(1) else: exit(0) # Business action combination def run_step(): result = True try: auto_cover_list = [ step_1, step_2, step_3 ] for func in auto_cover_list: func_name = func.__name__ print("Executing: %s" % func_name) func_result = func() if not func_result: result = False break except: result = False finally: if not result: exit(1) else: exit(0) if __name__ == '__main__': # start-up init_gpio() while True: if GPIO.input(button_start) == 0: try: p_run = Process(target=run_step, daemon=True) p_run.start() # Monitor emergency stop signal while p_run.is_alive(): if GPIO.input(button_stop) == 0: p_run.terminate() break else: time.sleep(0.1) if p_run.exitcode == 0 or p_run.exitcode is None: print("Successful execution") else: print("Execution failed") except: print("Execution failed") elif GPIO.input(button_reset) == 0: p_reset = Process(target=run_reset, daemon=True) p_reset.start() # Monitor emergency stop signal while p_reset.is_alive(): if GPIO.input(button_stop) == 0: p_reset.terminate() break else: time.sleep(0.1) elif GPIO.input(button_stop) == 0: # Release the program after the emergency stop button is released while True: if GPIO.input(button_stop) == 0: time.sleep(0.1) else: break else: time.sleep(0.1)