STM32F4 Multiple motors with cases

Below is the motordriver.c code I’ve written. My goal is to execute a specific scenario where sometimes 3-4 motors need to operate simultaneously. I have arranged this scenario using a case structure. For example:

case 1200:
    X_MotorSet(1, 40, 200, 14000, backward);
    B_MotorSet(1, 40, 200, 2500, forward);

In this case, I want the X and B motors to run simultaneously. The parameters in the code are as follows (translated from Turkish to English): min_speed, max_speed, ramp, target, direction.

However, the software doesn’t work as expected. First, the X motor runs, and only after it finishes, the B motor starts. How can I prevent this? What I actually want is for the X motor to take a step, then the B motor to take a step, and so on, alternating their movements.

Could you help me with this? Is there something I’m missing in the code? How can I achieve this with a case structure?

/*
 * MotorDriver.c
 *
 *  Created on: Jan 11, 2023
 *      Author: ARGE
 */

#include "stm32f4xx.h"
#include "main.h"
#include "MotorDriver.h"
#include "RelayDriver.h"
#include "SPI_Transfer.h"
#include "Tarifler.h"

extern struct MotorName_t MotorName;

extern TIM_HandleTypeDef htim1;
extern TIM_HandleTypeDef htim2;
extern TIM_HandleTypeDef htim3;


void MotorDriver_Init(){

  HAL_TIM_Base_Start_IT(&htim1);
  HAL_TIM_Base_Start_IT(&htim2);
  HAL_TIM_Base_Start_IT(&htim3);

  HAL_GPIO_WritePin(EN_X_GPIO_Port, EN_X_Pin, GPIO_PIN_SET);
  HAL_GPIO_WritePin(EN_Y_GPIO_Port, EN_Y_Pin, GPIO_PIN_SET);
  HAL_GPIO_WritePin(EN_A_GPIO_Port, EN_A_Pin, GPIO_PIN_SET);
  HAL_GPIO_WritePin(EN_B_GPIO_Port, EN_B_Pin, GPIO_PIN_SET);

  HAL_GPIO_WritePin(CS_X_GPIO_Port, CS_X_Pin, GPIO_PIN_SET);
  HAL_GPIO_WritePin(CS_Y_GPIO_Port, CS_Y_Pin, GPIO_PIN_SET);
  HAL_GPIO_WritePin(CS_A_GPIO_Port, CS_A_Pin, GPIO_PIN_SET);
  HAL_GPIO_WritePin(CS_B_GPIO_Port, CS_B_Pin, GPIO_PIN_SET);


  HAL_GPIO_WritePin(CS_X_GPIO_Port, CS_X_Pin, GPIO_PIN_RESET);
  ConfigDriver(XMotor, CS_X_GPIO_Port, CS_X_Pin);
  HAL_GPIO_WritePin(CS_X_GPIO_Port, CS_X_Pin, GPIO_PIN_SET);

  HAL_GPIO_WritePin(CS_Y_GPIO_Port, CS_Y_Pin, GPIO_PIN_RESET);
  ConfigDriver(YMotor, CS_Y_GPIO_Port, CS_Y_Pin);
  HAL_GPIO_WritePin(CS_Y_GPIO_Port, CS_Y_Pin, GPIO_PIN_SET);

  HAL_GPIO_WritePin(CS_A_GPIO_Port, CS_A_Pin, GPIO_PIN_RESET);
  ConfigDriver(AMotor, CS_A_GPIO_Port, CS_A_Pin);
  HAL_GPIO_WritePin(CS_A_GPIO_Port, CS_A_Pin, GPIO_PIN_SET);

  HAL_GPIO_WritePin(CS_B_GPIO_Port, CS_B_Pin, GPIO_PIN_RESET);
  ConfigDriver(BMotor, CS_B_GPIO_Port, CS_B_Pin);
  HAL_GPIO_WritePin(CS_B_GPIO_Port, CS_B_Pin, GPIO_PIN_SET);
  }

//Motor Yonlerinde bir farklılık olduğunda senaryo ve sw konumları ile ilgili
//guncellemeye gereksinim bırakmaması için bu kısımdan değiştirilmelidir.
void MotorYon(uint8_t MotorNo, uint8_t Yon) {
    switch (MotorNo) {
        case XMotor:
            if (Yon == geri)
                HAL_GPIO_WritePin(DIR_X_GPIO_Port, DIR_X_Pin, GPIO_PIN_SET);
            else if (Yon == ileri)
                HAL_GPIO_WritePin(DIR_X_GPIO_Port, DIR_X_Pin, GPIO_PIN_RESET);
            MotorName.X[yon] = Yon;
            break;
        case YMotor:
            if (Yon == ileri)
                HAL_GPIO_WritePin(DIR_Y_GPIO_Port, DIR_Y_Pin, GPIO_PIN_RESET);
            else if (Yon == geri)
                HAL_GPIO_WritePin(DIR_Y_GPIO_Port, DIR_Y_Pin, GPIO_PIN_SET);
            MotorName.Y[yon] = Yon;
            break;
        case AMotor:
            if (Yon == geri)
                HAL_GPIO_WritePin(DIR_A_GPIO_Port, DIR_A_Pin, GPIO_PIN_SET);
            else if (Yon == ileri)
                HAL_GPIO_WritePin(DIR_A_GPIO_Port, DIR_A_Pin, GPIO_PIN_RESET);
            MotorName.A[yon] = Yon;
            break;
        case BMotor:
            if (Yon == ileri)
                HAL_GPIO_WritePin(DIR_B_GPIO_Port, DIR_B_Pin, GPIO_PIN_SET);
            else if (Yon == geri)
                HAL_GPIO_WritePin(DIR_B_GPIO_Port, DIR_B_Pin, GPIO_PIN_RESET);
            MotorName.B[yon] = Yon;
            break;
    }
}



void MotorEnable(int MotorNo, int Durum) {
    switch (MotorNo) {
        case XMotor:
            if (Durum == ac)
                HAL_GPIO_WritePin(EN_X_GPIO_Port, EN_X_Pin, GPIO_PIN_RESET);
            else if (Durum == kapat)
                HAL_GPIO_WritePin(EN_X_GPIO_Port, EN_X_Pin, GPIO_PIN_SET);
            break;
        case YMotor:
            if (Durum == ac)
                HAL_GPIO_WritePin(EN_Y_GPIO_Port, EN_Y_Pin, GPIO_PIN_RESET);
            else if (Durum == kapat)
                HAL_GPIO_WritePin(EN_Y_GPIO_Port, EN_Y_Pin, GPIO_PIN_SET);
            break;
        case AMotor:
            if (Durum == ac)
                HAL_GPIO_WritePin(EN_A_GPIO_Port, EN_A_Pin, GPIO_PIN_RESET);
            else if (Durum == kapat)
                HAL_GPIO_WritePin(EN_A_GPIO_Port, EN_A_Pin, GPIO_PIN_SET);
            break;
        case BMotor:
            if (Durum == ac)
                HAL_GPIO_WritePin(EN_B_GPIO_Port, EN_B_Pin, GPIO_PIN_RESET);
            else if (Durum == kapat)
                HAL_GPIO_WritePin(EN_B_GPIO_Port, EN_B_Pin, GPIO_PIN_SET);
            break;

    }
}

/*
rampa:1-500 arasında; 500 rampa fazla, 1 düşük rampa
min_hiz:1
max_hiz:1-100 arasında
motor_hedef:1-2.147483648 step adımı arasında
*/
void Ramp(int32_t Motor[6]){
    if(Motor[rampa]>200){
        Motor[rampa]-=(500/Motor[rampa]);//1 er 1 er veya 2şer azalt//Gecikme Azalır, Hız artar
        delay_us(MotorName.X[rampa]);
        }
    else if(Motor[rampa]>20 && Motor[rampa]<200){
        Motor[rampa]-=(1000/Motor[rampa]);//20Ms olana kadar hız artar
        delay_us(Motor[rampa]);
        }
    else{//4000/40 = 10Ms maksimum hıza ayarlanmış olur.
        Motor[rampa] = 4000/Motor[max_hiz];//max hız min gecikme
        delay_us(Motor[rampa]);
    }
}


void X_MotorDrive() {
    while(MotorName.X[motor_konum] <= MotorName.X[motor_hedef]){
            HAL_GPIO_TogglePin(STEP_X_GPIO_Port, STEP_X_Pin); //motor_hiz,motor_pulse,motor_konum,max_hiz,yon,rampa_egim
            MotorName.X[motor_konum]++;
            Ramp(MotorName.X);//Çağrılan motor parametreleriyle rampa hesaplanarak burada gecikme sağlanır.
    }
        HAL_GPIO_WritePin(EN_X_GPIO_Port, EN_X_Pin, GPIO_PIN_SET);

}

void Y_MotorDrive() {
    while (MotorName.Y[motor_konum] <= MotorName.Y[motor_hedef]) {
        HAL_GPIO_TogglePin(STEP_Y_GPIO_Port, STEP_Y_Pin); //motor_hiz,motor_pulse,motor_konum,max_hiz,yon,rampa_egim
        MotorName.Y[motor_konum]++;
        Ramp(MotorName.Y);//Çağrılan motor parametreleriyle rampa hesaplanarak burada gecikme sağlanır.
    }
        HAL_GPIO_WritePin(EN_Y_GPIO_Port, EN_Y_Pin, GPIO_PIN_SET);
}

//***************************************************************

void A_MotorDrive() {
    while (MotorName.A[motor_konum] <= MotorName.A[motor_hedef]) {
        HAL_GPIO_TogglePin(STEP_A_GPIO_Port, STEP_A_Pin); //motor_hiz,motor_pulse,motor_konum,max_hiz,yon,rampa_egim
        MotorName.A[motor_konum]++;
        Ramp(MotorName.A);//Çağrılan motor parametreleriyle rampa hesaplanarak burada gecikme sağlanır.
    }
        HAL_GPIO_WritePin(EN_A_GPIO_Port, EN_A_Pin, GPIO_PIN_SET);
}

void B_MotorDrive() {
    while (MotorName.B[motor_konum] <= MotorName.B[motor_hedef]) {
        HAL_GPIO_TogglePin(STEP_B_GPIO_Port, STEP_B_Pin); //motor_hiz,motor_pulse,motor_konum,max_hiz,yon,rampa_egim
        MotorName.B[motor_konum]++;
        Ramp(MotorName.B);//Çağrılan motor parametreleriyle rampa hesaplanarak burada gecikme sağlanır.
    }
        HAL_GPIO_WritePin(EN_B_GPIO_Port, EN_B_Pin, GPIO_PIN_SET);
}


void X_MotorSet(int32_t Min_Hiz, int32_t Max_Hiz, int32_t Rampa, int32_t Mesafe, uint8_t Yon) {

    if (HAL_GPIO_ReadPin(LIMIT_X_GPIO_Port, LIMIT_X_Pin) == 0 && Yon == ileri) {
        MotorName.Home[XMotor] = HomeYapildi;
    } else {
        MotorName.X[rampa] = Rampa;
        MotorName.X[min_hiz] = Min_Hiz;
        MotorName.X[max_hiz] = Max_Hiz;
        MotorName.X[motor_hedef] = Mesafe;
        MotorName.X[motor_konum] = 1;
        MotorYon(XMotor, Yon);
        MotorEnable(XMotor, ac);
        X_MotorDrive();
    }
}

void Y_MotorSet(int32_t Min_Hiz, int32_t Max_Hiz, int32_t Rampa, int32_t Mesafe, uint8_t Yon) {

    if (HAL_GPIO_ReadPin(LIMIT_Y_GPIO_Port, LIMIT_Y_Pin) == 1 && Yon == ileri){
        MotorName.Home[YMotor] = HomeYapildi;
    } else {
        MotorName.Y[rampa] = Rampa;
        MotorName.Y[min_hiz] = Min_Hiz;
        MotorName.Y[max_hiz] = Max_Hiz;
        MotorName.Y[motor_hedef] = Mesafe;
        MotorName.Y[motor_konum] = 1;
        MotorYon(YMotor, Yon);
        MotorEnable(YMotor, ac);
        Y_MotorDrive();
    }
}

//***************************************************************************

void A_MotorSet(int32_t Min_Hiz, int32_t Max_Hiz, int32_t Rampa, int32_t Mesafe, uint8_t Yon) {

    if (HAL_GPIO_ReadPin(LIMIT_A_GPIO_Port, LIMIT_A_Pin) == 1 && Yon == ileri){
        MotorName.Home[AMotor] = HomeYapildi;
    } else {
        MotorName.A[rampa] = Rampa;
        MotorName.A[min_hiz] = Min_Hiz;
        MotorName.A[max_hiz] = Max_Hiz;
        MotorName.A[motor_hedef] = Mesafe;
        MotorName.A[motor_konum] = 1;
        MotorYon(AMotor, Yon);
        MotorEnable(AMotor, ac);
        A_MotorDrive();
    }
}

void B_MotorSet(int32_t Min_Hiz, int32_t Max_Hiz, int32_t Rampa, int32_t Mesafe, uint8_t Yon) {

    if (HAL_GPIO_ReadPin(LIMIT_B_GPIO_Port, LIMIT_B_Pin) == 1 && Yon == geri){
        MotorName.Home[BMotor] = HomeYapildi;
    } else {
        MotorName.B[rampa] = Rampa;
        MotorName.B[min_hiz] = Min_Hiz;
        MotorName.B[max_hiz] = Max_Hiz;
        MotorName.B[motor_hedef] = Mesafe;
        MotorName.B[motor_konum] = 1;
        MotorYon(BMotor, Yon);
        MotorEnable(BMotor, ac);
        B_MotorDrive();
    }
}


//***************************************************************************
//****************************************************************************





















I implemented the scenario using a case structure where multiple motors are configured to run simultaneously. For example:

case 1200:
    X_MotorSet(1, 40, 200, 14000, backward);
    B_MotorSet(1, 40, 200, 2500, forward);

I expected the X and B motors to move alternately, with one motor taking a step and then the other motor taking a step. However, in practice, the software executes the commands sequentially, with the X motor completing its entire movement before the B motor starts. I was expecting both motors to alternate or interleave their steps.

3

I was expecting both motors to alternate or interleave their steps.

I implemented the scenario using a case structure where multiple
motors are configured to run simultaneously. For example:

case 1200:
    X_MotorSet(1, 40, 200, 14000, backward);
    B_MotorSet(1, 40, 200, 2500, forward);

The first function is executed, followed by the second one. Nothing is parallel here.

You need (if you want main loop) to write functions which only do one thing without any delays and check what to do next. But cant wait fro the next phase.

You need to implement such a non blocking state machine.

Like every other function in your program, X_MotorSet does what it does: you call it, it runs, and returns when it’s done. Then control proceeds to the next statement, which in your case is a call to B_MotorSet.

I expected the X and B motors to move alternately, with one motor taking a step and then the other motor taking a step

In that case, you need different functions, or perhaps to call these functions with different parameters. You need the function to move the motor one step, and return. And, like read(2), you need that function to indicate when the motor is “done”, whatever that means.

Then you want a loop that runs each motor one step at a time until … something. When both motors are done? That’s up to you.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật