makerbase-mks / MKS-SERVO42B

MKS SERVO42B is 3d printer closed loop stepper motor NEMA17 MKS SERVO42 developed by Makerbase that prevents losing steps. CPU is STM32F103C8T6 ARM 32-bit Cortex™-M3 CPU Core,72 MHz. Magnetic encoder is Allegro's A1333LLETR-T Contactless 0° to 360° angle sensor IC ,12bit .This Project open source hardware and code,support platformio build and upload firmware...
https://www.aliexpress.com/item/33032696338.html?spm=a2g0o.store_home.productList_8356958.pic_1
GNU General Public License v3.0
166 stars 70 forks source link

move command scaling as MISFITTECH code suggests #20

Closed Quas7 closed 3 years ago

Quas7 commented 3 years ago

This is a pullrequest for this issue. It looks like a part of the original MISFITTECH code was not included (see diff). The original code scales the correction signal first by 511 (max sinewave amplitude?) and afterwards by 3300 (max output current of the PWM?). The MKS code only divides by 3300 that should result in much harder corrections and maybe overshoots and oscillations around steady state.

With the additional scaling I get less vibration around 0 in my setup. Also it seems to behave a bit smoother. Please verify for yourself, if this improves the behavior. I assume, it can also be tuned similarly via the PID values but quantiziation errors might be a limit for this route.

lonelymyp commented 3 years ago
vrefSin = ((int32_t)mA*(int64_t)abs(sin))/SINE_MAX;
vrefSin = (uint16_t)(mA * fastAbs(sin) / 3300);

It seems to me that the first line does not make sense. the vrefSin variable is rewritten twice and as a result, only the value from the second formula remains.

Quas7 commented 3 years ago

@lonelymyp I think, you are right. It should be rather be (3300*SINE_MAX) in the denominator. Maybe you just propose the correct code here as you are the original poster of the issue and I just stepped up as nobody pushed a PR? ;)

lonelymyp commented 3 years ago

@Quas7 In the original, the conversion was done in two steps, apparently for simplicity. Original code for sine: dacSin=((int32_t)mA(int64_t)abs(sin))/SINE_MAX; dacSin=(int32_t)((int64_t)dacSin(DAC_MAX))/3300;

In our case, it should look like this: vrefSin = (uint16_t)(mA fastAbs(sin) / SINE_MAX); vrefSin = (uint16_t)((uint16_t)vrefSin(DAC_MAX))/3300;

and you also need to define #define DAC_MAX (0x01FFL) The original is 0x01FFL But I don't know what value should be in our case

Quas7 commented 3 years ago

I assume, DAC_MAX should be substituted by the max value of timer3 that is generating the PWM duty cycle? So it should be 65535 for this 16bit timer.

Did not yet dive into the HAL documentation, if this can be set differently than 16bit couting but it should be traceable from this snippet from board.c

    //Init TIM3
    TIM_TimeBaseInitTypeDef         TIM_TimeBaseStructure;
    TIM_TimeBaseStructure.TIM_Period = VREF_MAX;                                    //reload c
    TIM_TimeBaseStructure.TIM_Prescaler = 0;                                            //72MHz
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(VREF_TIM, &TIM_TimeBaseStructure);

    TIM_OCInitTypeDef           TIM_OCInitStructure;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = 0;
    TIM_OC3Init(VREF_TIM, &TIM_OCInitStructure);    //TIM3 CH3
    TIM_OC4Init(VREF_TIM, &TIM_OCInitStructure);    //TIM3 CH4

    TIM_OC3PreloadConfig(VREF_TIM, TIM_OCPreload_Enable);
    TIM_OC4PreloadConfig(VREF_TIM, TIM_OCPreload_Enable);

    TIM_Cmd(VREF_TIM, ENABLE);
}
dzid26 commented 3 years ago

You guys are guessing the implemention based on a different software. What is wrong with existing implementation? The timer counts to the maximum value from sine lookup, thus you don't divide it by 511.

lonelymyp commented 3 years ago

I counted on a piece of paper, the result of the Misfit formula coincides with the MKS formula if DAC_MAX = 1FF (511). I made a mistake somewhere earlier, because it seemed to me that the result was different. Probably enough to remove the offset 1500 and no need to correct the formula.

It would be nice now to return the calibration procedure PID_Autotune(void)