In some cases, the zero-cross point might be detected earlier or later than the ideal case due to noise or other factors such as motor particularities.
A filtering method will be used to avoid an unwanted behavior that can get the motor out of lock.
Based on the above requirements, a first-order IIR filter is chosen under the form of a
moving average low-pass filter using the formula
timerValue = (uint32_t)(((uint32_t)previous_zero_cross_time * (MOTOR_DIVISION_FACTOR - 1) +
(uint32_t)current_zero_cross_time)) / MOTOR_DIVISION_FACTOR;
Ideally, for faster computation, the filter coefficient
(MOTOR_DIVISION_FACTOR
) must be a power of two, as it can be
implemented using bit shifting with specific core instructions.
The input and output values are unsigned 16-bit values, thus, to prevent an overflow during the multiplication of y(n-1), as well as the total sum, the operations are done using casting to 32-bit unsigned values.
For the scope of this application, a value of 4 for the filter coefficient was considered the best fit.