Encoder reading, best approach (for this case) - Page 1
Forum section: electronics / general

author: rvalente
author_rank: Frequent Contributor
timestamp: January 21, 2020, 12:57:38 am
content: Hello Mates,i'm looking for the best approach to read this encoder.There is a truck axle axle differential fitted with a 100 teeth encoder wheel in each side with a variable reluctance pick-up.The sensor frequency can go up to 1350Hz. I do not need to get axle position but speed and acceleration (accel is very important),I do not to sample it very fast, 10 samples/s seems adequate.As prototype, I'm using a STM32F103C8T6 (bluepill board, very convenient + STMCUBE IDE), I've set the timer 2+3 as 32bit in capture mode, 10MHz clock to the timer and every teeth gives an interruption, I get two captures, make the delta T and get the time, them calculate the frequency.Its working fine by now with very good precision, but I'm concerned with this excess of interruptions, so I'm thinking about using the DMA to help me, is this a good ideal?But, I do not know if my approach is the best, maybe change the timer to counter mode and read from time-to-time (delta T strategy).The application is very similar to a ABS/EBS system, how do they read frequency? I've been looking for some papers (IEEE/SAE) but have not found many details, a lot of the content for encoder reading is focused in servo drivers application (some papers are attached)Greetings, Renan

author: ejeffrey
author_rank: Super Contributor
timestamp: January 21, 2020, 04:28:09 am
content: Why are you concerned about the excess interrupts? Will you be adding more computation such that the micro can't keep up any more? 1300 (or 2600?) Interrupts per second shouldn't be an extraordinary number as long as the ISR is simple.

author: rvalente
author_rank: Frequent Contributor
timestamp: January 21, 2020, 10:52:06 am
content: Quote from: ejeffrey on January 21, 2020, 04:28:09 amI'm not sure why this is bothering me, just trying to do everything short and less resource hungry as possible. The micro has plenty of power but, maybe using the DMA instead will help me, never used the STM32, do not know how powerful it is

author: JOEBOBSICLE
author_rank: Regular Contributor
timestamp: January 21, 2020, 10:06:11 pm
content: This is something that should be done in hardware to be properly scoocum. This sounds like quadrature decoding ishThe stm32H7 has quadrature decoding, not sure if that can be used. Alternatively this is something that could be put down on an FPGA in a week with an SPI interface outDMA could help if you store the last N timer captures by autoincrementing the memory address. Normally that's how DMA can help, you reduce the number of interrupts by collecting N samples before a DMA complete interrupt happen.Don't let your friends do quadrature decoding in software

author: Nominal Animal
author_rank: Super Contributor
timestamp: January 21, 2020, 10:55:49 pm
content: STM32F103C8T6 16-bit timers 2, 3, and 4 do have quadrature decoding in hardware.That is, if you connect the encoder to say, timer 2 input capture pins 1 and 2 (PA0 and PA1 or PA15 and PB3), and configure TIM2 properly, the timer hardware will track the encoder automatically (without processor intervention). You just read the 16-bitTIM2->CNT(timer 2 counter) whenever you need to know the current position of the encoder. (Note that this wraps around above 232-1 = 65535, or at about 328 rotations with your 100-teeth wheel, using both edges mode.)I recommend you also enable the DWT cycle counter, and useDWT->CYC_CNTto measure the elapsed time in cycles. That way, you only need an another timer interrupt (not TIM2) to semi-regularly sample the difference inTIM2->CNTandDWT->CYC_CNT(the latter increasing monotonically, but wrapping around at 232cycles); the ratio of the differences is the average velocity during that period. (If you handle decreasing and increasing TIM2->CNT differently, you can use unsigned integer arithmetic for both CNT and CYC_CNT to handle the wraparound correctly.) By comparing changes in successive periods (and their total duration), you get acceleration. By comparing acceleration in successive periods (and their duration), you get jerk (which is the third derivative of position, or second derivative of velocity; the rate of change in acceleration).This is all described in the STM32F103xx Reference Manual (here, I believe; at least I found all that info from here).

author: techman-001
author_rank: Frequent Contributor
timestamp: January 21, 2020, 10:59:32 pm
content: Quote from: rvalente on January 21, 2020, 10:52:06 amA STM32 is like a nuclear explosion (in terms of power) for your simple stated requirement.I'm wondering why you wouldn't just use one or more of the STM32 inbuilt timer counters to get your frequency/time data from that simple magnetic reluctance sensor ?I have a STM32F051 running at 8Mhz with three prioritized interrupts. One is triggered by each pulse in a 70 Hz burst of about 1500 pulses, one is a timer window and the last one is triggered by a push button. The mcu still has eons to do other tasks as each interrupt is handled in fractions of microseconds.

author: NorthGuy
author_rank: Super Contributor
timestamp: January 21, 2020, 11:55:55 pm
content: There's no premium for not using resources you already have.2600 interrupts per second is very little actually.Whatever else you do (other than you have done) will only increase the latency (delay since the dent passing to the point where your CPU has the number) thus decreasing performance with no benefits.

author: langwadt
author_rank: Super Contributor
timestamp: January 22, 2020, 12:22:17 am
content: a few kHz is nothing for an stm32, just setup a timer for period measurement, in the capture interrupt you can calculate you speed/acceleration if you hit the update interrupt wheel is rotating slower that the timer can reach