Page 1 of 1

Pulse counter without interrupts

Posted: Mon Dec 30, 2019 6:19 pm
by TravisT
I am looking to do pulse counting that does not rely on interrupts on a STM32. I have some other communication and functions that I would worry might cause missed pulses if they have a higher priority, or the counter interrupt those important functions.

My hope is to use one of the counters with external sources and then periodically read the counter, calculate the pulses based on the delta from the last time the counter was read (Also compensate for rollover).

I was looking at the encoder functionality which seems to be supported on some of the timers (Ch1 and CH2), but not sure of the reason for this. The Datasheet says TIM2, TIM3, TIM4, and TIM5 should all handle encoder mode. My plan is to use a STM32F413 so I of course worry some changes between that and the Pyboard F405 will cause issues.

I have not really needed to use timers for much other than PWM outputs, and was hoping somebody with more experience would have some thoughts on how to best implement this.

Another post covers a lot of what I need to know, but that was about 5 years old and I am digging around hoping or assuming some things have changed or improved with the timer libraries.
viewtopic.php?f=2&t=346&p=1814&hilit=et ... nter#p1814

There is also this one that shows some basics on using the Encoder mode, which seems the most promising.
viewtopic.php?t=1735

Now maybe just using the Encoder setup with the two timers active is the quickest and easiest path.

Re: Pulse counter without interrupts

Posted: Mon Dec 30, 2019 8:00 pm
by OutoftheBOTS_
You will need to read the reference manual for the MCU that your using and see what registers you need to set. I have done this in C on STM32F103 but would be very similar on the MCU that your using. Iused it to read the Quadrature encoders on a motor and did the same thing as u read the count periodicity then calculated both the absolute position and the speed. then set the count to 32768 so that I would never get over flow.

I looked for my code and I think this is the setup code here

Code: Select all

	RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
	TIM3->SMCR = TIM_SMCR_SMS_0 | TIM_SMCR_SMS_1;
	TIM3->PSC = 0;   //set prescale
	TIM3->CR1 |= TIM_CR1_CEN;    //enable channel 1
	TIM3->CNT = 32768;
Encoder mode does have single encoder and Quadrature encoder. If your just going to count a pulse then you need to use single encoder mode.

Re: Pulse counter without interrupts

Posted: Thu Jan 02, 2020 1:19 am
by TravisT
Thanks for the help. Really helped to push me in the right direction. I was able to search more specifically about using the encoder inputs I found some more resources. Of course some of the helpful resources are from Dave (dhylands).

Discussion thread
viewtopic.php?f=6&t=901&p=28663&hilit=E ... ode#p28663

And some of Dave's examples
https://github.com/dhylands/upy-example ... encoder.py
https://github.com/dhylands/upy-example ... ncoder2.py
https://github.com/dhylands/upy-example ... ncoder3.py

That is good to hear that you used it int a similar way. Sounds like single encoder mode would work perfect, and I like your idea of resetting the counter on each read to avoid dealing with the counter overflowing.

Looks like Timer 1,8 (advanced) and Timer 2,5 (general purpose) have encoder modes. Timer 2 seems to be nice and available on my pinout needs and one that is referenced well in documentation.

I definitely need to play with this to make sure it can count a single pulse input, I have very little experience with rotary encoders. But definitely promising. Dave's examples also made me realize I can test on a Pyboard board with a couple jumpers without too much effort.