src/ESPStepperMotorServer_RestAPI.cpp
void ESPStepperMotorServer_RestAPI::handleHomingRequest(AsyncWebServerRequest *request)
{
    this->logDebugRequestUrl(request);

    if (!request->hasParam("id"))
    {
        request->send(400, "application/json", "{\"error\": \"Missing stepper id parameter\"}");
        return;
    }

    int stepperIndex = request->getParam("id")->value().toInt();
    ESPStepperMotorServer_StepperConfiguration *stepperConfiguration = this->_stepperMotorServer->getCurrentServerConfiguration()->getStepperConfiguration(stepperIndex);
    if (stepperConfiguration == NULL)
    {
        request->send(404, "application/json", "{\"error\": \"No stepper configuration found for given stepper id\"}");
        return;
    }

    float speedInStepsPerSecond = 0;
    if (request->hasParam("speed"))
    {
        speedInStepsPerSecond = request->getParam("speed")->value().toFloat();
        if (speedInStepsPerSecond <= 0)
        {
            request->send(400, "application/json", "{\"error\": \"Value for homing speed (in steps/second) must be larger than 0\"}");
            return;
        }
    }
    else
    {
        request->send(400, "application/json", "{\"error\": \"Missing parameter for speed (in steps/second)\"}");
        return;
    }

    float accelInStepPerSecondSquare = 0;
    if (request->hasParam("accel"))
    {
        accelInStepPerSecondSquare = request->getParam("accel")->value().toFloat();
        if (accelInStepPerSecondSquare <= 0)
        {
            request->send(400, "application/json", "{\"error\": \"Acceleration value must be larger than 0\"}");
            return;
        }
    }

    unsigned int maxSteps = 2000000000;
    if (request->hasParam("maxSteps"))
    {
        maxSteps = request->getParam("maxSteps")->value().toInt();
        if (maxSteps < 1)
        {
            request->send(400, "application/json", "{\"error\": \"Max number of steps during homing must be larger than 0\"}");
            return;
        }
    }

    ESPStepperMotorServer_PositionSwitch *switchConfig;
    signed char directionTowardHome = 1;

    signed char forcedDirectionTowardHome = 0;
    if (request->hasParam("direction"))
    {
        forcedDirectionTowardHome = request->getParam("direction")->value().toInt();
        if (forcedDirectionTowardHome != 1 && forcedDirectionTowardHome != -1)
        {
            request->send(400, "application/json", "{\"error\": \"Invalid direction value given. Allowed values are 1 and -1\"}");
            return;
        }
    }

    byte gpioPinForSwitch = 0;
    //TOOD: implement proper ISR handling for custom switch parameter if not linked to existing stepper
    if (request->hasParam("switchId"))
    {
        int switchIndex = request->getParam("switchId")->value().toInt();
        switchConfig = this->_stepperMotorServer->getCurrentServerConfiguration()->getSwitch(switchIndex);
        if (switchConfig == NULL)
        {
            request->send(400, "application/json", "{\"error\": \"No switch configuration found for given switch id\"}");
            return;
        }
        gpioPinForSwitch = switchConfig->getIoPinNumber();
        //TODO: this detection is not exactely precise, since the switch could also be a combined Begin / End switch
        if (switchConfig->isTypeBitSet(SWITCHTYPE_LIMITSWITCH_POS_BEGIN_BIT))
        {
            directionTowardHome = -1;
        }
    }
    else
    {
        //Try to find pin by looking for configured limit switches of type homing switch for selected stepper motor config
        switchConfig = this->_stepperMotorServer->getCurrentServerConfiguration()->getFirstConfiguredLimitSwitchForStepper(stepperIndex);
        if (switchConfig == NULL)
        {
            request->send(400, "application/json", "{\"error\": \"No existing limit switch configuration found the stepper with the given id\"}");
            return;
        }
        gpioPinForSwitch = switchConfig->getIoPinNumber();
        // determine direction section for the case no explicit switch ID was provided
        if (switchConfig->isTypeBitSet(SWITCHTYPE_LIMITSWITCH_POS_BEGIN_BIT))
        {
            directionTowardHome = -1;
        }
    }

    ESPStepperMotorServer_Logger::logDebugf("Received homing request for stepper with id %i and limit switch on GPIO %i. Homing speed to be set to %.2f steps per second. Max step limit set to %i\n", stepperIndex, gpioPinForSwitch, speedInStepsPerSecond, maxSteps);

    ESP_FlexyStepper *stepper = stepperConfiguration->getFlexyStepper();
    if (speedInStepsPerSecond > 0)
    {
        stepper->setSpeedInStepsPerSecond(speedInStepsPerSecond);
    }
    if (accelInStepPerSecondSquare > 0)
    {
        stepper->setAccelerationInStepsPerSecondPerSecond(accelInStepPerSecondSquare);
    }

    if (forcedDirectionTowardHome != 0)
    {
        stepper->setDirectionToHome(forcedDirectionTowardHome);
    }
    else
    {
        stepper->setDirectionToHome(directionTowardHome);
    }
    stepper->goToLimitAndSetAsHome(NULL, maxSteps);
    request->send(200, "application/json", "{\"status\": \"homing procedure started\"}");
    return;
}
/**
 * handler for the REST endpoint to perform a homing run.
 * This will call the goToLimitAndSetAsHome() function in the flexyStepper instance.
 * It will require that a home/limit switch is configured for this stepper, otherwise stepper will "never" (an absolute limit of 2000000000 steps is configured by default to somewhat limit the movement) come to a halt 
 * Required POST parameters: 
 *      id (id of the stepper motor to pefrom the homing command for)
 *      speed: the speed in steps per second to perform the homing command with
 * Optional POST parameters: 
 *      switchId:  the id of the configured switch to use as limit switch, if parameter is omited the position switch from the configurtration of the stepper motor will be used, if none is configured, operation will fail)
 *      accel: the acceleration for the homing procdeure in steps/sec^2, if ommitted the previously defined acceleration in the flexy stepper instance will be used
 *      maxSteps: this parameter defines the maximum number of steps to perform before cancelling the homing procedure. This is kind of a safeguard to prevent endless spinning of the stepper motor. Defaults to 2000000000 steps
 */
handler for the REST endpoint to perform a homing run.
This will call the goToLimitAndSetAsHome() function in the flexyStepper instance.
handler for the REST endpoint to perform a homing run . This will call the goToLimitAndSetAsHome () function in the flexyStepper instance .
void ESPStepperMotorServer_RestAPI::handleHomingRequest(AsyncWebServerRequest *request)
{
    this->logDebugRequestUrl(request);
    if (!request->hasParam("id"))
    {
        request->send(400, "application/json", "{\"error\": \"Missing stepper id parameter\"}");
        return;
    }
    int stepperIndex = request->getParam("id")->value().toInt();
    ESPStepperMotorServer_StepperConfiguration *stepperConfiguration = this->_stepperMotorServer->getCurrentServerConfiguration()->getStepperConfiguration(stepperIndex);
    if (stepperConfiguration == NULL)
    {
        request->send(404, "application/json", "{\"error\": \"No stepper configuration found for given stepper id\"}");
        return;
    }
    float speedInStepsPerSecond = 0;
    if (request->hasParam("speed"))
    {
        speedInStepsPerSecond = request->getParam("speed")->value().toFloat();
        if (speedInStepsPerSecond <= 0)
        {
            request->send(400, "application/json", "{\"error\": \"Value for homing speed (in steps/second) must be larger than 0\"}");
            return;
        }
    }
    else
    {
        request->send(400, "application/json", "{\"error\": \"Missing parameter for speed (in steps/second)\"}");
        return;
    }
    float accelInStepPerSecondSquare = 0;
    if (request->hasParam("accel"))
    {
        accelInStepPerSecondSquare = request->getParam("accel")->value().toFloat();
        if (accelInStepPerSecondSquare <= 0)
        {
            request->send(400, "application/json", "{\"error\": \"Acceleration value must be larger than 0\"}");
            return;
        }
    }
    unsigned int maxSteps = 2000000000;
    if (request->hasParam("maxSteps"))
    {
        maxSteps = request->getParam("maxSteps")->value().toInt();
        if (maxSteps < 1)
        {
            request->send(400, "application/json", "{\"error\": \"Max number of steps during homing must be larger than 0\"}");
            return;
        }
    }
    ESPStepperMotorServer_PositionSwitch *switchConfig;
    signed char directionTowardHome = 1;
    signed char forcedDirectionTowardHome = 0;
    if (request->hasParam("direction"))
    {
        forcedDirectionTowardHome = request->getParam("direction")->value().toInt();
        if (forcedDirectionTowardHome != 1 && forcedDirectionTowardHome != -1)
        {
            request->send(400, "application/json", "{\"error\": \"Invalid direction value given. Allowed values are 1 and -1\"}");
            return;
        }
    }
    byte gpioPinForSwitch = 0;
    if (request->hasParam("switchId"))
    {
        int switchIndex = request->getParam("switchId")->value().toInt();
        switchConfig = this->_stepperMotorServer->getCurrentServerConfiguration()->getSwitch(switchIndex);
        if (switchConfig == NULL)
        {
            request->send(400, "application/json", "{\"error\": \"No switch configuration found for given switch id\"}");
            return;
        }
        gpioPinForSwitch = switchConfig->getIoPinNumber();
        if (switchConfig->isTypeBitSet(SWITCHTYPE_LIMITSWITCH_POS_BEGIN_BIT))
        {
            directionTowardHome = -1;
        }
    }
    else
    {
        switchConfig = this->_stepperMotorServer->getCurrentServerConfiguration()->getFirstConfiguredLimitSwitchForStepper(stepperIndex);
        if (switchConfig == NULL)
        {
            request->send(400, "application/json", "{\"error\": \"No existing limit switch configuration found the stepper with the given id\"}");
            return;
        }
        gpioPinForSwitch = switchConfig->getIoPinNumber();
        if (switchConfig->isTypeBitSet(SWITCHTYPE_LIMITSWITCH_POS_BEGIN_BIT))
        {
            directionTowardHome = -1;
        }
    }
    ESPStepperMotorServer_Logger::logDebugf("Received homing request for stepper with id %i and limit switch on GPIO %i. Homing speed to be set to %.2f steps per second. Max step limit set to %i\n", stepperIndex, gpioPinForSwitch, speedInStepsPerSecond, maxSteps);
    ESP_FlexyStepper *stepper = stepperConfiguration->getFlexyStepper();
    if (speedInStepsPerSecond > 0)
    {
        stepper->setSpeedInStepsPerSecond(speedInStepsPerSecond);
    }
    if (accelInStepPerSecondSquare > 0)
    {
        stepper->setAccelerationInStepsPerSecondPerSecond(accelInStepPerSecondSquare);
    }
    if (forcedDirectionTowardHome != 0)
    {
        stepper->setDirectionToHome(forcedDirectionTowardHome);
    }
    else
    {
        stepper->setDirectionToHome(directionTowardHome);
    }
    stepper->goToLimitAndSetAsHome(NULL, maxSteps);
    request->send(200, "application/json", "{\"status\": \"homing procedure started\"}");
    return;
}
void ESPStepperMotorServer_RestAPI :: handleHomingRequest ( AsyncWebServerRequest * request ) { this -> logDebugRequestUrl ( request ) ; if ( ! request -> hasParam ( " " ) ) { request -> send ( 400 , " " , " \" \" \" \" " ) ; return ; } int stepperIndex = request -> getParam ( " " ) -> value ( ) . toInt ( ) ; ESPStepperMotorServer_StepperConfiguration * stepperConfiguration = this -> _stepperMotorServer -> getCurrentServerConfiguration ( ) -> getStepperConfiguration ( stepperIndex ) ; if ( stepperConfiguration == NULL ) { request -> send ( 404 , " " , " \" \" \" \" " ) ; return ; } float speedInStepsPerSecond = 0 ; if ( request -> hasParam ( " " ) ) { speedInStepsPerSecond = request -> getParam ( " " ) -> value ( ) . toFloat ( ) ; if ( speedInStepsPerSecond <= 0 ) { request -> send ( 400 , " " , " \" \" \" \" " ) ; return ; } } else { request -> send ( 400 , " " , " \" \" \" \" " ) ; return ; } float accelInStepPerSecondSquare = 0 ; if ( request -> hasParam ( " " ) ) { accelInStepPerSecondSquare = request -> getParam ( " " ) -> value ( ) . toFloat ( ) ; if ( accelInStepPerSecondSquare <= 0 ) { request -> send ( 400 , " " , " \" \" \" \" " ) ; return ; } } unsigned int maxSteps = 2000000000 ; if ( request -> hasParam ( " " ) ) { maxSteps = request -> getParam ( " " ) -> value ( ) . toInt ( ) ; if ( maxSteps < 1 ) { request -> send ( 400 , " " , " \" \" \" \" " ) ; return ; } } ESPStepperMotorServer_PositionSwitch * switchConfig ; signed char directionTowardHome = 1 ; signed char forcedDirectionTowardHome = 0 ; if ( request -> hasParam ( " " ) ) { forcedDirectionTowardHome = request -> getParam ( " " ) -> value ( ) . toInt ( ) ; if ( forcedDirectionTowardHome != 1 && forcedDirectionTowardHome != -1 ) { request -> send ( 400 , " " , " \" \" \" \" " ) ; return ; } } byte gpioPinForSwitch = 0 ; if ( request -> hasParam ( " " ) ) { int switchIndex = request -> getParam ( " " ) -> value ( ) . toInt ( ) ; switchConfig = this -> _stepperMotorServer -> getCurrentServerConfiguration ( ) -> getSwitch ( switchIndex ) ; if ( switchConfig == NULL ) { request -> send ( 400 , " " , " \" \" \" \" " ) ; return ; } gpioPinForSwitch = switchConfig -> getIoPinNumber ( ) ; if ( switchConfig -> isTypeBitSet ( SWITCHTYPE_LIMITSWITCH_POS_BEGIN_BIT ) ) { directionTowardHome = -1 ; } } else { switchConfig = this -> _stepperMotorServer -> getCurrentServerConfiguration ( ) -> getFirstConfiguredLimitSwitchForStepper ( stepperIndex ) ; if ( switchConfig == NULL ) { request -> send ( 400 , " " , " \" \" \" \" " ) ; return ; } gpioPinForSwitch = switchConfig -> getIoPinNumber ( ) ; if ( switchConfig -> isTypeBitSet ( SWITCHTYPE_LIMITSWITCH_POS_BEGIN_BIT ) ) { directionTowardHome = -1 ; } } ESPStepperMotorServer_Logger :: logDebugf ( " \n " , stepperIndex , gpioPinForSwitch , speedInStepsPerSecond , maxSteps ) ; ESP_FlexyStepper * stepper = stepperConfiguration -> getFlexyStepper ( ) ; if ( speedInStepsPerSecond > 0 ) { stepper -> setSpeedInStepsPerSecond ( speedInStepsPerSecond ) ; } if ( accelInStepPerSecondSquare > 0 ) { stepper -> setAccelerationInStepsPerSecondPerSecond ( accelInStepPerSecondSquare ) ; } if ( forcedDirectionTowardHome != 0 ) { stepper -> setDirectionToHome ( forcedDirectionTowardHome ) ; } else { stepper -> setDirectionToHome ( directionTowardHome ) ; } stepper -> goToLimitAndSetAsHome ( NULL , maxSteps ) ; request -> send ( 200 , " " , " \" \" \" \" " ) ; return ; }
handler for the REST endpoint to perform a homing run.
handler for the REST endpoint to perform a homing run .
//TOOD: implement proper ISR handling for custom switch parameter if not linked to existing stepper //TODO: this detection is not exactely precise, since the switch could also be a combined Begin / End switch //Try to find pin by looking for configured limit switches of type homing switch for selected stepper motor config // determine direction section for the case no explicit switch ID was provided