Quantcast
Viewing all articles
Browse latest Browse all 1309

Python • GPIO busy in Flask Service

Hi guys,

I'm facing difficulties with my raspberry pi using the gpiozero library. Here is what I have:

I'm running a web application that executes multiple python scripts. I have mechanical buttons that are connected to GPIO pins 15 and 25 acting as a limit switch for a linear stage. In python file 1 I have a manual mode in which I can move the linear stage in forward and backward and do a check if I reached the limit to then stop the movement.
On the other hand in python file 2 I have a fully automated code which relies on the same buttons.

Once executed any movement in file 1 I can no longer exectue file 2 with the error message "GPIO busy". If I first execute file 2 and then file 1 everything still works, but going back to file 2 again then it doesn't work.

I tried to use GPIO.cleanup() or deleting the buttons after each execution in file 1 but it didn't help.

File 1

Code:

import RPi.GPIO as GPIOimport timefrom DRV8825 import DRV8825from gpiozero import Buttonimport ioimport timeimport cv2from time import strftime from signal import pausefrom gpiozero import RGBLEDfrom colorzero import Colorimport numpyclass ManualAxis:    def SwitchLaserState(self,  state = False):        try:            if state == "True":                print('Turning On laser')                #GPIO set up                GPIO.setmode(GPIO.BCM)                GPIO.setup(21, GPIO.OUT)                GPIO.output(21, GPIO.HIGH)            else:                print('Turning Off laser')                #GPIO set up                GPIO.setmode(GPIO.BCM)                GPIO.setup(21, GPIO.OUT)                GPIO.output(21, False)            return True        except Exception as e:            print(e)            return False        def move_laser_towards_camera(self, steps_to_move: int):        result = True        try:            #declaring the sensors as buttons in pins 25 and 14            sensor1 = Button(25)            sensor2 = Button(15)            Motor1 = DRV8825(dir_pin=13, step_pin=19, enable_pin=12, mode_pins=(16, 17, 20))            """            # 1.8 degree: nema23, nema14            # softward Control :            # 'fullstep': A cycle = 200 steps            # 'halfstep': A cycle = 200 * 2 steps            # '1/4step': A cycle = 200 * 4 steps            # '1/8step': A cycle = 200 * 8 steps            # '1/16step': A cycle = 200 * 16 steps            # '1/32step': A cycle = 200 * 32 steps            """            Motor1.SetMicroStep('hardward','fullstep')            start = time.monotonic()                        if not sensor2.is_pressed:                i = 0                while sensor2.is_pressed == False and i < steps_to_move:                        Motor1.TurnStep(Dir='forward', steps=1, stepdelay = 0.0005)                        i = i + 1                if sensor2.is_pressed == True:                        print('Limit reached')                        result = False            else:                print('Limit reached')                result = False                                    print(time.monotonic() - start)            Motor1.Stop()            print("motor stopped")            """            # 28BJY-48:            # softward Control :            # 'fullstep': A cycle = 2048 steps            # 'halfstep': A cycle = 2048 * 2 steps            # '1/4step': A cycle = 2048 * 4 steps            # '1/8step': A cycle = 2048 * 8 steps            # '1/16step': A cycle = 2048 * 16 steps            # '1/32step': A cycle = 2048 * 32 steps            """            return result        except Exception as e:            print(e)            # GPIO.cleanup()            print ("\nMotor stop")            Motor1.Stop()            raise CustomError("A custom error occurred in the child method.")            def move_laser_away_from_camera(self, steps_to_move: int):        result = True        try:            #declaring the sensors as buttons in pins 25 and 14            sensor1 = Button(25)            sensor2 = Button(15)                        Motor1 = DRV8825(dir_pin=13, step_pin=19, enable_pin=12, mode_pins=(16, 17, 20))                        """            # 1.8 degree: nema23, nema14            # softward Control :            # 'fullstep': A cycle = 200 steps            # 'halfstep': A cycle = 200 * 2 steps            # '1/4step': A cycle = 200 * 4 steps            # '1/8step': A cycle = 200 * 8 steps            # '1/16step': A cycle = 200 * 16 steps            # '1/32step': A cycle = 200 * 32 steps            """                        Motor1.SetMicroStep('hardward','fullstep')            start = time.monotonic()            if not sensor1.is_pressed:                i = 0                while not sensor1.is_pressed and i < steps_to_move:                        Motor1.TurnStep(Dir='backward', steps=1, stepdelay = 0.0005)                        i = i + 1                if sensor1.is_pressed:                    print('Limit reached')                    result = False            else:                print('Limit reached')                result = False                                                #Motor1.TurnStep(Dir='backward', steps=step_number, stepdelay = 0.0005) #backward: towards the housing            print(time.monotonic() - start)            Motor1.Stop()            print("motor stopped")            """            # 28BJY-48:            # softward Control :            # 'fullstep': A cycle = 2048 steps            # 'halfstep': A cycle = 2048 * 2 steps            # '1/4step': A cycle = 2048 * 4 steps            # '1/8step': A cycle = 2048 * 8 steps            # '1/16step': A cycle = 2048 * 16 steps            # '1/32step': A cycle = 2048 * 32 steps            """                        return result        except Exception as e:            print(e)            # GPIO.cleanup()            print ("\nMotor stop")            Motor1.Stop()            raise CustomError("A custom error occurred in the child method.")        def move_laser_to_center(self):        try:            led = RGBLED(17,27,22)            led.color = Color("orange")            #setting up motor            Motor1 = DRV8825(dir_pin=13, step_pin=19, enable_pin=12, mode_pins=(16, 17, 20))            Motor1.SetMicroStep('hardward','fullstep')            print("motor ready")            #declaring the sensors as buttons in pins 25 and 14            sensor1 = Button(25)            sensor2 = Button(15)            time.sleep(0.1)            #start centering            print("centering started")            if not(sensor2.is_pressed):            #if not in 0 position                while not(sensor2.is_pressed):                    Motor1.TurnStep(Dir='forward', steps = 1, stepdelay = 0.0005)                                steps = 0            if (sensor2.is_pressed):                   time.sleep(0.1)                      print("going to the other limit")                while not(sensor1.is_pressed) : #move motor until sensor1 is activated (end of stage)                      #move backward                    Motor1.TurnStep(Dir='backward', steps = 1, stepdelay = 0.0005)                    steps = steps+1            center_steps = steps // 2            print("steps to center position=" ,center_steps)            if (sensor1.is_pressed):                time.sleep(0.1)                print("going to center position")            for i in range(center_steps):                Motor1.TurnStep(Dir='forward', steps = 1, stepdelay = 0.0005)            print ("moved to center position")            Motor1.Stop()            return True                      except Exception as e:            print(e)            # GPIO.cleanup()            print ("\nMotor stop")            Motor1.Stop()            return Falseclass CustomError(Exception):    """Custom exception for specific errors."""    pass
File 2

Code:

from picamera2 import Picamera2from picamera2.encoders import JpegEncoderfrom picamera2.outputs import FileOutputimport ioimport timefrom datetime import datetimefrom threading import Event, Threadimport cv2import RPi.GPIO as GPIOfrom time import strftime #import os #from gpiozero import Buttonfrom signal import pausefrom gpiozero import RGBLEDfrom colorzero import Colorfrom numpy import savetxtfrom numpy import asarrayimport numpyimport scipy.ioimport argparseimport jsonimport requestsimport sysdef send_callback(id, message, percentage):    callback_response = {            "id": id,            "status": "Progress",            "message": message,            "data": percentage            }    callback_url = "http://localhost:8000/api/callback/status"  # Replace with the URL of the other web application's endpoint    requests.post(callback_url, json=callback_response)print("In referencing script")parser = argparse.ArgumentParser(description='A measurement script.')parser.add_argument('parameter', help='Data parameter.')args = parser.parse_args()data = json.loads(args.parameter)print("data")id = data["Id"]MotorDir = [    'forward',    'backward',]ControlMode = [    'hardward',    'softward',]counter = 0 #classes related to the motor set-upclass DRV8825():    def __init__(self, dir_pin, step_pin, enable_pin, mode_pins):        self.dir_pin = dir_pin        self.step_pin = step_pin                self.enable_pin = enable_pin        self.mode_pins = mode_pins                GPIO.setmode(GPIO.BCM)        GPIO.setwarnings(False)        GPIO.setup(self.dir_pin, GPIO.OUT)        GPIO.setup(self.step_pin, GPIO.OUT)        GPIO.setup(self.enable_pin, GPIO.OUT)        GPIO.setup(self.mode_pins, GPIO.OUT)            def digital_write(self, pin, value):        GPIO.output(pin, value)            def Stop(self):        self.digital_write(self.enable_pin, 0)        def SetMicroStep(self, mode, stepformat):        """        (1) mode            'hardward' :    Use the switch on the module to control the microstep            'software' :    Use software to control microstep pin levels                Need to put the All switch to 0        (2) stepformat            ('fullstep', 'halfstep', '1/4step', '1/8step', '1/16step', '1/32step')        """        microstep = {'fullstep': (0, 0, 0),                     'halfstep': (1, 0, 0),                     '1/4step': (0, 1, 0),                     '1/8step': (1, 1, 0),                     '1/16step': (0, 0, 1),                     '1/32step': (1, 0, 1)}        print ("Control mode:",mode)        if (mode == ControlMode[1]):            print ("set pins")            self.digital_write(self.mode_pins, microstep[stepformat])            def TurnStep(self, Dir, steps, stepdelay=0.08):                 if (Dir == MotorDir[0]):            #print ("forward")            self.digital_write(self.enable_pin, 1)            self.digital_write(self.dir_pin, 0)        elif (Dir == MotorDir[1]):            #print ("backward")            self.digital_write(self.enable_pin, 1)            self.digital_write(self.dir_pin, 1)        else:            print ("the dir must be : 'forward' or 'backward'")            self.digital_write(self.enable_pin, 0)            return                        for i in range(steps):            self.digital_write(self.step_pin, True)            time.sleep(stepdelay)            self.digital_write(self.step_pin, False)            time.sleep(stepdelay)#image variablesnmb_ref_img = 21powder_img_distance = 1500starting_steps = 750stepwidth = 2nmb_powder_img = powder_img_distance // stepwidthled = RGBLED(17,27,22)led.color = Color("orange")#create new folderdateformatted=strftime("%y%m%d_%H:%M:%S")folderwithdate = "/home/admin/myssd/" + str(dateformatted) #use this directory as parameter for second scriptos.mkdir(folderwithdate)    #setting up motorMotor1 = DRV8825(dir_pin=13, step_pin=19, enable_pin=12, mode_pins=(16, 17, 20))Motor1.SetMicroStep('hardward','fullstep')print("motor ready")#camera set uppicam2 = Picamera2()config = picam2.create_still_configuration(main={"size": (2800,2100)}, buffer_count=4, )picam2.configure(config)picam2.set_controls({"AnalogueGain": 1.0, "ExposureTime": 50000, "AeEnable": 0})picam2.start()#declaring the sensors as buttons in pins 25 and 14sensor1 = Button(25)sensor2 = Button(15)#activate laserGPIO.setmode(GPIO.BCM)GPIO.setup(21, GPIO.OUT)GPIO.output(21, GPIO.HIGH)time.sleep(2)#start referencingprint("referencing started")send_callback(id, "1. Start referencing", "20")if not(sensor2.is_pressed):#if not in 0 position    while not(sensor2.is_pressed):        Motor1.TurnStep(Dir='forward', steps = 1, stepdelay = 0.0005)        steps = 0if (sensor2.is_pressed):       time.sleep(1)          print("going to the other limit")    while not(sensor1.is_pressed) : #move motor until sensor1 is activated (end of stage)          #move backward        Motor1.TurnStep(Dir='backward', steps = 1, stepdelay = 0.0005)        steps = steps+1center_steps = steps // 2print("steps to center position=" ,center_steps)if (sensor1.is_pressed):    time.sleep(1)    print("going to center position")for i in range(center_steps):    Motor1.TurnStep(Dir='forward', steps = 1, stepdelay = 0.0005)print ("moved to center position")send_callback(id, "2. Center position found", "40")time.sleep(2)#taking reference pictures, total of 21 imagesMotor1.TurnStep(Dir='backward', steps=500, stepdelay = 0.0005)start = time.monotonic()for i in range(nmb_ref_img):    r = picam2.capture_array("main")    cv2.imwrite(folderwithdate+"/reference_"+str(i)+".jpg", r, [cv2.IMWRITE_JPEG_QUALITY, 70])    Motor1.TurnStep(Dir='forward', steps=50, stepdelay = 0.0005)print(time.monotonic() - start)send_callback(id, "3. Reference images captured", "80")Motor1.TurnStep(Dir='backward', steps=550+starting_steps, stepdelay = 0.0005)Motor1.TurnStep(Dir='forward', steps = 10, stepdelay = 0.0005)#turn off laserGPIO.output(21, False)Motor1.Stop()print(folderwithdate)send_callback(id, "4. Referencing completed", "100")
Any idea how I can resolve this?

Thanks in advance!

Statistics: Posted by LuMa97 — Fri Jan 10, 2025 12:45 pm



Viewing all articles
Browse latest Browse all 1309

Trending Articles