2024-10-24 12:40 AM
Hello everyone,
I'm working on a dual motor control project using an STM32F4 with Hall sensors to track motor speeds. Both motors are controlled via CAN commands, and I can successfully run both motors. However, while Motor 2 speed is being tracked and displayed in real time on the LCD, Motor 1 speed always shows 0 RPM on the display, even though the motor is running.
Here’s what I’ve tried so far:
I suspect the issue might be related to how the Hall sensor pulses are handled for Motor 1 in the interrupt handler or how the speed is being calculated.
Could anyone point out what I might be missing or suggest how to fix the speed tracking issue for Motor 1?
Here’s my code for reference:
<
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "key.h"
#include "can.h"
#include "adc.h"
#include "timer.h"
#include "stm32f4xx_syscfg.h"
#include "stm32f4xx_exti.h"
#include "misc.h"
#define CAN_SJW_DEFAULT CAN_SJW_1TQ
#define CAN_BS1_DEFAULT CAN_BS1_7TQ
#define CAN_BS2_DEFAULT CAN_BS2_6TQ
#define CAN_BAUD_PRESCALER 6
#define TARGET_RPM_M1 230
#define TARGET_RPM_M2 100
#define MAX_PWM 165
#define MIN_PWM 0
#define N_MAX 5000
#define POLE_PAIRS 3
#define IPBCLK 60000000
#define QT_PRESCALER 128
#define PERIOD_TO_SPEED (IPBCLK * 60 / (N_MAX * QT_PRESCALER * POLE_PAIRS))
#define HALL_A_PIN_M1 GPIO_Pin_6
#define HALL_B_PIN_M1 GPIO_Pin_7
#define HALL_C_PIN_M1 GPIO_Pin_8
#define HALL_PORT_M1 GPIOB
#define HALL_A_PIN_M2 GPIO_Pin_0
#define HALL_B_PIN_M2 GPIO_Pin_1
#define HALL_C_PIN_M2 GPIO_Pin_2
#define HALL_PORT_M2 GPIOG
volatile uint32_t hall_pulse_count_m1 = 0;
volatile uint32_t hall_pulse_count_m2 = 0;
float actual_rpm_m1 = 0;
float actual_rpm_m2 = 0;
int error_flag_m1 = 0;
int error_flag_m2 = 0;
extern volatile uint32_t sys_tick_counter;
int last_pin_state_A1 = -1, last_pin_state_B1 = -1, last_pin_state_C1 = -1;
int last_pin_state_A2 = -1, last_pin_state_B2 = -1, last_pin_state_C2 = -1;
int hall_sensor_error_m1 = 0, hall_sensor_error_m2 = 0;
uint8_t motor_running_m1 = 0;
uint8_t motor_running_m2 = 0;
float Kp_m1 = 0.8, Ki_m1 = 0.15, Kd_m1 = 0.1;
float integral_m1 = 0, previous_error_m1 = 0;
float target_speed_m1 = TARGET_RPM_M1;
float Kp_m2 = 0.7, Ki_m2 = 0.12, Kd_m2 = 0.08;
float integral_m2 = 0, previous_error_m2 = 0;
float target_speed_m2 = TARGET_RPM_M2;
uint16_t pwm_output_m1 = 0;
uint16_t pwm_output_m2 = 0;
void GPIO_HallSensor_Init(void);
void EXTI9_5_IRQHandler(void);
float calculate_speed_m1(void);
float calculate_speed_m2(void);
void display_status(float speed_m1, int error_flag_m1, float speed_m2, int error_flag_m2);
uint16_t PID_Controller(float setpoint, float measured_speed, float *Kp, float *Ki, float *Kd, float *integral, float *previous_error);
void TIM3_PWM_Init(uint32_t arr, uint32_t psc);
void set_pwm_duty_cycle_m1(uint16_t pwm_value);
void set_pwm_duty_cycle_m2(uint16_t pwm_value);
uint32_t millis(void);
void check_hall_sensor_wires_m1(void);
void check_hall_sensor_wires_m2(void);
void handle_CAN_command(uint8_t *data);
int main(void) {
uint8_t can_rx_buf[8];
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
delay_init(168);
uart_init(115200);
LED_Init();
LCD_Init();
KEY_Init();
TIM3_PWM_Init(255, 0);
TIM3_PWM_Init(255, 0);
CAN1_Mode_Init(CAN_SJW_DEFAULT, CAN_BS2_DEFAULT, CAN_BS1_DEFAULT, CAN_BAUD_PRESCALER, CAN_Mode_Normal);
GPIO_HallSensor_Init();
SysTick_Config(SystemCoreClock / 1000);
POINT_COLOR = RED;
LCD_ShowString(30, 50, 200, 16, 16, "STM32 Motor Control");
POINT_COLOR = BLUE;
while (1) {
check_hall_sensor_wires_m1();
check_hall_sensor_wires_m2();
if (CAN1_Receive_Msg(can_rx_buf)) {
handle_CAN_command(can_rx_buf);
}
if (motor_running_m1) {
actual_rpm_m1 = calculate_speed_m1();
pwm_output_m1 = PID_Controller(target_speed_m1, actual_rpm_m1, &Kp_m1, &Ki_m1, &Kd_m1, &integral_m1, &previous_error_m1);
set_pwm_duty_cycle_m1(pwm_output_m1);
} else {
set_pwm_duty_cycle_m1(0);
}
if (motor_running_m2) {
actual_rpm_m2 = calculate_speed_m2();
pwm_output_m2 = PID_Controller(target_speed_m2, actual_rpm_m2, &Kp_m2, &Ki_m2, &Kd_m2, &integral_m2, &previous_error_m2);
set_pwm_duty_cycle_m2(pwm_output_m2);
} else {
set_pwm_duty_cycle_m2(0);
}
display_status(actual_rpm_m1, hall_sensor_error_m1, actual_rpm_m2, hall_sensor_error_m2);
delay_ms(100);
}
} />
2024-10-24 08:30 AM