encoder rotation speed detection

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Guys,

 

I know this subject has been raised a number of times, but I haven't found anything appropriate, or perhaps I'm not phrasing the search correctly.

 

I have an Atmega324PB (@20Mhz from external clock) with 16 encoders attached.  Code uses PCINT to capture rotation and it works well with reliable accuracy (don't miss any increments).   Hardware debounce is in use.  Board is designed for 2 humans turning the knobs so working on only 4 changing at any one time.

 

Positions are relayed to remote device using TWI.

 

My conundrum is how can I determine speed of rotation so that if an encoder is turned rapidly I can increment position in 10's.  Testing shows that I can move a max of ~9 detents with a quick flick.

 

Any ideas?  Timer perhaps, but I can't fathom how that might work.  I would rather the board manage the speed increase in incremental values rather than the remote end figuring it out.

 

Any pointers would be appreciated

 

regards

 

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

nikm wrote:
how can I determine speed of rotation so that if an encoder is turned rapidly I can increment position in 10's.
Well you have to "time it". If you get 6 encoder increments in 6 minutes you just move the thing by +6. If it all happens in 0.1s you move it by 60.

 

It does mean you may have to wait from registering one increment to the next to see if there's another one coming along close by. So perhaps something like if you get an increment, wait 0.1s. If you don't get another in that time then just +1 but if you do just keep in mind you are now at +2 and reset your timing count for the same period to see if yet another is coming and so on. When you finally time out add 10 * number of increments.

 

(or something along those lines anyway!) 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why would you use hardware debounce and pcints? It can all be done in software. Use a timer in ctc mode to poll each encoder. As a consequence it is easy to keep track of time. Speed is number of pulses per time unit. You might need to poll your encoders 1000 or 2000 times per second but keep an individual pulse count for each encoder say 10 times a second. Then if the count is above a certain value, set a flag that says ‘fast’ or similar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I guess it's because I went down the route of using Pcint's and it's working (apart from the 'fast' mode. Using hardware debounce simplifies the code (I have small caps on each input) and I'm using a state table.  I have to say the polling does have the benefits of figuring out if fast mode should be engaged though.

 

I'll have to get my head around switching to polling.

 

regards

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Basically you read the encoder A & B signal at a given rate. When you read it, poke the AB value into the state machine - that will give you step and direction. For each step, increment a count. Every, say 10ms (or whatever it works out in timer ticks) read the count a decide what to do based on the value. Then reset the count. Or you could do a first order IIR filter. It all depends on what you require. What you would do for a jog wheel for skipping through video would be different to something that might set a seconds count from 1..9999

 

Firstly determine your maximum pulse count that can be physically achieved. You want to oversample by at least 4 times. Then you need to factor in how many encoders you can read at one time then this gives you the required timer tick rate. Any more than a few kHz might be stretching the friendship - depends on what else the micro has to do.

 

 

If you need to save port pins, then you could wire the encoders in a 4x4 matrix. Four times A & B signals makes an 8 bit port. Then a select line for each of the rows. 12 port pins.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

nikm wrote:

My conundrum is how can I determine speed of rotation so that if an encoder is turned rapidly I can increment position in 10's.  Testing shows that I can move a max of ~9 detents with a quick flick.

Any ideas?  Timer perhaps, but I can't fathom how that might work.  I would rather the board manage the speed increase in incremental values rather than the remote end figuring it out.

So long as you are not missing any steps, you should be able to capture time in each edge, and take a difference to get dT. 

You can check how much time is needed, to see if the MCU can do a 1/x calculation.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

very simple

 

Set ratea=1    ...that is the default: one click==> 1 increase/decrease in reported position

When knob A gets a step, you add or subtract (depending on direction) ratea to/from position A, then report this positionA final result to the user. 

 

Also:

     You also set last_time_A to record a dumb timer count value of when this update occurred.   The dumb timer just counts & doesn't need to do anything other than keep counting...tick...tick...tick... 

     If the present timer count is within 5 ticks of last_time_a  (meaning it is moving again somewhat quick), then  add 1 to ratea (if ratea<10 to limit ratea to 10 max)).   Note you have to account for the timer number possibly rolling over, but that is easy.

     If the present timer count is more than 8 ticks from last_time_a, then set ratea back to 1   ...this means you stopped for a certain amount of time & revert to 1st gear.   

 

This will give a smooth acceleration, so as you spin the knob fast the numbers will "pick up speed"..faster & faster they go!   You can have other interesting accel, such as instead of adding one to ratea, you can double it each time (up to your max of 10 or whatever).  So then it picks up speed very rapidly.

If the knob stops long enough (8), then the gearshift goes back to 1st gear.

 

So basically you are setting a value between 1 .2.3.4...10 to add to the current positions each time you detect knob  motion.

 

You do a similar thing for each knob, they all share the same dumb timer ...tick...tick...tick... 

 

Try it out with one knob, see if you like it...then apply same thing to all.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Fri. Nov 20, 2020 - 02:28 AM