Closed Quas7 closed 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.
@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? ;)
@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
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);
}
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.
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)
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.