2020-08-26 10:36 AM
Hello,
I need a help in Motor frequency calculation with more precision.
I am using STM32F070CB for my application. My requirements are
1) Monitor the Motor frequency based on quadrature pulses.
2) If Frequency varies by +/-15%, need to process some safety activity within 100 milli seconds.
3) find the direction of rotation.
Data: Motor nominal frequency is 100Hz ( when motor running at full speed)
I have configured TIM3 in Encoder mode in such a way that counter counts in UP/DOWN based on the direction of the motor rotation.
I have configured another general purpose timer (TIM6) for 50ms periodic Interrupt.
My Idea is to read the Encoder counter value for every 50ms (in TIM6 interrupt) and clear the Encoder counter value. That is, (counter value / 50ms ) is the frequency.
The problem here I am facing is, the calculated frequency is fluctuating ( 80Hz to 100Hz ) rarely which allows me in misjudgment for the requirement 2.
(Note: My earlier implementation for the same requirement was without using encoder. I have used Capture/compare feature in same timer where the counter was clocked by internal 24MHz clock). Every complete pulse will give an interrupt and the counter value at the time of interrupt will be one pulse width. 1/pulse width is my frequency. Same method is applied for second signal and finding the direction based on phase shift. This method is serving my purpose but leaving me with more interrupts and some extra processing time. So I tried to use Encoder)
Observation:
Encoder counter value is not always constant. Counter values for every 50ms timer are 5, 5, 4, 5, 4, 5....
When the count value changing from 5 to 4, calculated frequency is changing from 100Hz to 80Hz and then back to 100Hz, where the actual system is running constantly at 100Hz.
I have tried another method by averaging the sequence of counts now with the same above data, calculated frequency is changing from 100 Hz to 92Hz.
My Expectations:
Deviation shall not exceed +/- 2Hz.
If the counter values are more, then the deviation will be minimum. I can not increase the periodicity as per the requirement 2.
Need clarifications:
Sorry for the long description, but I just want to provide every detail.
Thanks in advance.
Solved! Go to Solution.
2020-08-26 11:54 AM
Forward CH1 to another timer through master-slave timer connection, or connect externally; and in that other timer timestamp using the internal clock, as Clive said. To achieve 2% error you must have an encoder which won't produce jitter more than that (ideally much less), won't produce glitches due to vibration, etc.
Direction is determined in the timer in encoder mode simply by reading the TIMx_CR1.DIR bit.
JW
2020-08-26 11:26 AM
Is the encoder signal frequency 100 Hz (10ms) or higher? Should be a manageable interrupt rate.
Pretty sure testing a 20 Hz / 50 ms you'll not be in-sync with the encoder pulses.
I'd probably use PWM Input, and also look at long-term time stamping of edges.
Assuming 10 pulses of less than 8.5 ms periodicity, or greater than 11.5 ms would be flagging. Likely to see violation when changing direction or stopping.
2020-08-26 11:49 AM
Hi Clive1,
Thanks for your response.
//Is the encoder signal frequency 100 Hz (10ms) or higher? Should be a manageable interrupt rate.
Yes, Motor’s maximum frequency that I suppose to monitor is 100Hz.
//Pretty sure testing a 20 Hz / 50 ms you'll not be in-sync with the encoder pulses
Yes I agree on this. With the system given, counting on pulses at constant time period may leads to missing synchronisation. But as of my knowledge Encoder peripheral in MCU is implemented By considering pulse counts but not with the pulse widths.
//I'd probably use PWM Input, and also look at long-term time stamping of edges.
As I mentioned in the note, if I go with the interrupts on every rising edge, I need to process two interrupts for one pulse since the input is in quadrature signals, second signals also I need to monitor for direction detection purpose. In future, there is a possibility of increasing the Motor’s maximum frequency. In this case Interrupts are too early and it will cause the core spend more time on Handler mode. This is the reason I have chosen to use Encoder.
please correct me if my understanding is incorrect.
2020-08-26 11:54 AM
Forward CH1 to another timer through master-slave timer connection, or connect externally; and in that other timer timestamp using the internal clock, as Clive said. To achieve 2% error you must have an encoder which won't produce jitter more than that (ideally much less), won't produce glitches due to vibration, etc.
Direction is determined in the timer in encoder mode simply by reading the TIMx_CR1.DIR bit.
JW
2020-08-26 12:07 PM
On which event I should read the another timer’s counter value?
as of my understanding, if I choose the period (ARR value) of encoder timer as 2 which means for 2 pulses, on the encoder’s interrupt I can read the another timer’s count value is nothing but the length of 2 pulses. This works in UP direction. But if Motor rotation is in down direction, then Encoder starts decrementing from 0 to 65535 and then to 65534... in this case encoder’s interrupt will not be for 2 pulses. Is there any way to overcome this?
2020-08-26 12:26 PM
>>On which event I should read the another timer’s counter value?
Encoder edges.
You'd free run the counter so you could measure the signals in the TIME DOMAIN
If you clocked the counter at 1 MHz, the 10,000us (10ms) interval would fit in the 16-bit count six times.
You could also use DMA to sample the timer to a buffer, if interrupting was too high.
2020-08-26 08:33 PM
Hey Waclawek and Clive,
Your recommendations helped me to find the answer for my Clarification 1. The Slave timer I can configure in Input capture(IC) mode.
By this, I can configure IC Prescaler with my choice of number of pulses(may require in case of High frequencies) and Counter value will be the frequency of Incoming signal. Direction status will be knowing from Encoder's Register (TIMx_CR1->DIR).
I think this method helps me a lot! Thank you very much both of you.