|
|
@@ -23,11 +23,11 @@
|
|
|
|
|
|
encoder_t g_encoder;
|
|
|
|
|
|
-static __INLINE u32 _abi_count(void) {
|
|
|
+static __INLINE s16 _abi_count(void) {
|
|
|
#ifdef ENCODER_CC_INVERT
|
|
|
- return (g_encoder.cpr - ENC_COUNT);
|
|
|
+ return (g_encoder.cpr - (s16)ENC_COUNT);
|
|
|
#else
|
|
|
- return ENC_COUNT;
|
|
|
+ return (s16)ENC_COUNT;
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
@@ -73,6 +73,7 @@ void encoder_init_clear(void) {
|
|
|
g_encoder.pwm_angle = 0.0f;
|
|
|
g_encoder.est_angle_counts = 0;
|
|
|
g_encoder.est_vel_counts = 0;
|
|
|
+ g_encoder.est_vel_cnt_filter = 0;
|
|
|
g_encoder.position = 0.0f;
|
|
|
g_encoder.interpolation = 0.0f;
|
|
|
//g_encoder.cali_angle = INVALID_ANGLE;
|
|
|
@@ -126,8 +127,9 @@ static __INLINE bool encoder_run_pll(float cnt) {
|
|
|
g_encoder.est_vel_counts = PLL_run(&g_encoder.est_pll, cnt, pll_comp);
|
|
|
g_encoder.est_angle_counts = g_encoder.est_pll.observer;
|
|
|
bool snap_to_zero_vel = false;
|
|
|
+ g_encoder.est_vel_cnt_filter = LowPass_Filter(g_encoder.est_vel_cnt_filter, g_encoder.est_vel_counts, 0.1f);
|
|
|
if (ABS(g_encoder.est_pll.out) < 0.5f * g_encoder.est_pll.DT * g_encoder.est_pll.ki) {
|
|
|
- g_encoder.est_vel_counts = g_encoder.est_pll.out = 0.0f; // align delta-sigma on zero to prevent jitter
|
|
|
+ g_encoder.est_vel_cnt_filter = g_encoder.est_vel_counts = g_encoder.est_pll.out = 0.0f; // align delta-sigma on zero to prevent jitter
|
|
|
snap_to_zero_vel = true;
|
|
|
}
|
|
|
return snap_to_zero_vel;
|
|
|
@@ -152,14 +154,32 @@ static __INLINE float _eccentricity_compensation(int cnt) {
|
|
|
u32 enc_pwm_err_ms = 0;
|
|
|
s16 enc_delta_err1 = 0;
|
|
|
s16 enc_delta_err2 = 0;
|
|
|
-static void encoder_detect_error(u32 cnt) {
|
|
|
+static s16 enc_r = 0;
|
|
|
+static s16 enc_cnt = 0;
|
|
|
+static s16 enc_last_cnt = 0;
|
|
|
+static s16 enc_test1 = 0;
|
|
|
+static s16 enc_test2 = 0;
|
|
|
+static s16 enc_test3 = 0;
|
|
|
+#define MAX_CPR_CNT_PER_CTL 40
|
|
|
+/* 9000RPM = 150 RPS = 150 * ENC_MAX_RES * FOC_CTRL_US = 39, 每个控制周期 39个count */
|
|
|
+static void encoder_detect_error(s16 cnt) {
|
|
|
#ifdef CONFIG_ENC_DETECT_ERR
|
|
|
static u32 _mayerr_cnt = 0;
|
|
|
if (ENCODER_NO_ERR == g_encoder.enc_maybe_err) {
|
|
|
s16 delta_cnt = cnt - g_encoder.last_cnt;
|
|
|
bool skip = false;
|
|
|
if (g_encoder.b_timer_ov) {
|
|
|
- delta_cnt = (cnt + ENC_MAX_RES) - g_encoder.last_cnt;
|
|
|
+ if((cnt > (ENC_MAX_RES - MAX_CPR_CNT_PER_CTL*2) && g_encoder.last_cnt > (ENC_MAX_RES - MAX_CPR_CNT_PER_CTL*2)) ||
|
|
|
+ (cnt < (MAX_CPR_CNT_PER_CTL*2) && g_encoder.last_cnt < (MAX_CPR_CNT_PER_CTL*2))) { //需要处理低速在overflow附近震荡
|
|
|
+ delta_cnt = cnt - g_encoder.last_cnt;
|
|
|
+ }else {
|
|
|
+ delta_cnt = (cnt + ENC_MAX_RES) - g_encoder.last_cnt;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if ((delta_cnt > 200) || (delta_cnt < -200)) {
|
|
|
+ enc_test1 = cnt;
|
|
|
+ enc_test2 = g_encoder.last_cnt;
|
|
|
+ enc_test3 = g_encoder.b_timer_ov;
|
|
|
}
|
|
|
#ifdef CONFIG_ENC_ERR_TEST
|
|
|
if (g_encoder.produce_error) {
|
|
|
@@ -170,9 +190,10 @@ static void encoder_detect_error(u32 cnt) {
|
|
|
g_encoder.last_delta_cnt = delta_cnt;
|
|
|
skip = true;
|
|
|
}
|
|
|
- if ((g_encoder.last_delta_cnt <= CONFIG_ENC_DIANOSTIC_MIN_CNT*1.2f) && get_delta_ms(g_encoder.pwm_time_ms) >= 4) {
|
|
|
+ if ((g_encoder.last_delta_cnt <= CONFIG_ENC_DIANOSTIC_MIN_CNT*1.2f) && get_delta_ms(g_encoder.pwm_time_ms) >= 8) {
|
|
|
g_encoder.enc_maybe_err = ENCODER_PWM_ERR;
|
|
|
enc_pwm_err_ms = get_delta_ms(g_encoder.pwm_time_ms);
|
|
|
+ enc_delta_err2 = (s16)((g_encoder.est_vel_counts/g_encoder.cpr) * 60.0f);
|
|
|
}
|
|
|
if (g_encoder.start_dianostic_cnt < 0xFFFF) {
|
|
|
g_encoder.start_dianostic_cnt ++;
|
|
|
@@ -204,7 +225,10 @@ static void encoder_detect_error(u32 cnt) {
|
|
|
if (_mayerr_cnt >= cnt_thr) {
|
|
|
g_encoder.enc_maybe_err = ENCODER_AB_ERR;
|
|
|
enc_delta_err1 = g_encoder.last_delta_cnt;
|
|
|
- enc_delta_err2 = delta_cnt;
|
|
|
+ enc_delta_err2 = (s16)((g_encoder.est_vel_counts/g_encoder.cpr) * 60.0f);
|
|
|
+ enc_r = r;
|
|
|
+ enc_cnt = cnt;
|
|
|
+ enc_last_cnt = g_encoder.last_cnt;
|
|
|
}
|
|
|
}else {
|
|
|
_mayerr_cnt = 0;
|
|
|
@@ -223,11 +247,16 @@ float encoder_get_theta(void) {
|
|
|
if (!g_encoder.b_index_found) {
|
|
|
return g_encoder.pwm_angle;
|
|
|
}
|
|
|
- u32 cnt = _abi_count();
|
|
|
+ s16 cnt = _abi_count();
|
|
|
__NOP();__NOP();__NOP();__NOP();
|
|
|
if (ENC_OverFlow()) {
|
|
|
cnt = _abi_count();
|
|
|
- g_encoder.b_timer_ov = true;
|
|
|
+ if((cnt > (ENC_MAX_RES - MAX_CPR_CNT_PER_CTL*2) && g_encoder.last_cnt > (ENC_MAX_RES - MAX_CPR_CNT_PER_CTL*2)) ||
|
|
|
+ (cnt < (MAX_CPR_CNT_PER_CTL*2) && g_encoder.last_cnt < (MAX_CPR_CNT_PER_CTL*2))) { //需要处理低速在overflow附近震荡
|
|
|
+ g_encoder.b_timer_ov = false;
|
|
|
+ }else {
|
|
|
+ g_encoder.b_timer_ov = true;
|
|
|
+ }
|
|
|
ENC_ClearUpFlags();
|
|
|
}
|
|
|
|
|
|
@@ -239,7 +268,7 @@ float encoder_get_theta(void) {
|
|
|
g_encoder.interpolation = 0.1f;
|
|
|
}else {
|
|
|
if (cnt == g_encoder.last_cnt) {
|
|
|
- g_encoder.interpolation += g_encoder.est_vel_counts * FOC_CTRL_US;
|
|
|
+ g_encoder.interpolation += g_encoder.est_vel_cnt_filter * FOC_CTRL_US;
|
|
|
if (g_encoder.interpolation > ENC_MAX_interpolation) {
|
|
|
g_encoder.interpolation = ENC_MAX_interpolation;
|
|
|
}else if (g_encoder.interpolation < -ENC_MAX_interpolation) {
|
|
|
@@ -364,10 +393,20 @@ void ENC_TIMER_Overflow(void) {
|
|
|
/*PWM 信号捕获一个周期的处理 */
|
|
|
static int pwm_count = 0;
|
|
|
static int pwm_check_count = 0;
|
|
|
+static int pwm_duty_err = 0;
|
|
|
+static float pwm_err_min = 0;
|
|
|
+static float pwm_err_max = 0;
|
|
|
void ENC_PWM_Duty_Handler(float t, float d) {
|
|
|
float duty = ENC_Duty(d, t);
|
|
|
if (duty < ENC_PWM_Min_P || duty > ENC_PWM_Max_P) {
|
|
|
- return;
|
|
|
+ pwm_duty_err++;
|
|
|
+ if (duty < ENC_PWM_Min_P) {
|
|
|
+ pwm_err_min = duty;
|
|
|
+ duty = ENC_PWM_Min_P;
|
|
|
+ }else {
|
|
|
+ pwm_err_max = duty;
|
|
|
+ duty = ENC_PWM_Max_P;
|
|
|
+ }
|
|
|
}
|
|
|
float Nr = ENC_Duty_2_Pluse_Nr(duty);
|
|
|
if (Nr < 0) {
|
|
|
@@ -417,7 +456,7 @@ float encoder_get_pwm_angle(void) {
|
|
|
}
|
|
|
|
|
|
float encoder_get_abi_angle(void) {
|
|
|
- u32 cnt = _abi_count();
|
|
|
+ s16 cnt = _abi_count();
|
|
|
float angle = ENC_Pluse_Nr_2_angle((float)cnt) * g_encoder.motor_poles + g_encoder.enc_offset;
|
|
|
rand_angle(angle);
|
|
|
return angle;
|
|
|
@@ -426,5 +465,8 @@ float encoder_get_abi_angle(void) {
|
|
|
void encoder_log(void) {
|
|
|
sys_debug("pwm %f, abi %f\n", encoder_get_pwm_angle(), encoder_get_abi_angle());
|
|
|
sys_debug("pwm count %d, I count %d\n", g_encoder.pwm_count, abi_I_delta);
|
|
|
- sys_debug("pwm freq %f, err %d\n", enc_get_pwm_freq(), g_encoder.enc_maybe_err);
|
|
|
+ sys_debug("pwm freq %f, err %d, %f, %f\n", enc_get_pwm_freq(), pwm_duty_err, pwm_err_min, pwm_err_max);
|
|
|
+ if (g_encoder.enc_maybe_err) {
|
|
|
+ sys_debug("E:%d,%d,%d,%d,%d,%d\n", enc_test1, enc_test2, enc_test3, enc_r, enc_cnt, enc_last_cnt);
|
|
|
+ }
|
|
|
}
|