Author Topic: Velocity from encoder with Timer Interrupts  (Read 10367 times)

0 Members and 1 Guest are viewing this topic.

Offline oneeveningTopic starter

  • Newbie
  • Posts: 7
Velocity from encoder with Timer Interrupts
« on: June 19, 2015, 12:04:46 pm »
Okay, for days I am struggling to calculate the velocity out of my quadrature encoder with arduino. My problem is the following;
Since I read the encoder with an ISR function, which is triggered by the A and B channels of the quadrature encoder, I cannot measure the time elapsed.
So, I thought that for velocity calculation, normal ISR is not appropriate. What I need to do is using a timer Interrupt.
However, my question is that; Can I use an ISR attached to a pin and also a timer interrupt at the same time. Would that lead a problem. For example my normal ISR is in progress to read the encoder increment and at that instead timer interrupt needs to be started. Would it terminate the normal ISR, or it would wait and right after normal ISR finished, timer interrupt would start ? How does it work ?
So my plan is to read the encoder with a normal ISR, this will change a variable called "encoder" and then there will be another parameter, which is only edited by timer interrupt, let's call it "timer" and it is initialized as "0". And assume that the timer interrupt works at 1Khz. So, I will do the following operations in the timer interrupt;

Quote
(encoder-timer)/0.001;
timer = encoder;

Which should simply calculate the rate of change of encoder ticks.
Any better ideas ?
 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3233
  • Country: gb
Re: Velocity from encoder with Timer Interrupts
« Reply #1 on: June 19, 2015, 12:28:19 pm »
Triggering interrupts from a quadrature encoder output is often not the best way to do things to start with, since contact bounce can trigger many more interrupt than you may be expecting. 

However, if you want to go this way then you could set up a timer and use the encoder output to trigger a timer capture event.  In the capture interrupt you can subtract the previous time from the current time to get the time between interrupts.

Provided you use unsigned math this work correctly even if the timer overflow occurs between two encoder edges, though the maximum possible you can measure is half the timers total period.  This means you will need some scheme to determine if the last time value is invalid.

 

Offline langwadt

  • Super Contributor
  • ***
  • Posts: 4391
  • Country: dk
Re: Velocity from encoder with Timer Interrupts
« Reply #2 on: June 19, 2015, 12:52:51 pm »
Triggering interrupts from a quadrature encoder output is often not the best way to do things to start with, since contact bounce can trigger many more interrupt than you may be expecting. 

However, if you want to go this way then you could set up a timer and use the encoder output to trigger a timer capture event.  In the capture interrupt you can subtract the previous time from the current time to get the time between interrupts.

Provided you use unsigned math this work correctly even if the timer overflow occurs between two encoder edges, though the maximum possible you can measure is half the timers total period.  This means you will need some scheme to determine if the last time value is invalid.

you don't need the capture interrupt you'd only need to set the timer for up capture, the captured value
can be read in the pin interrupt

 

Offline oneeveningTopic starter

  • Newbie
  • Posts: 7
Re: Velocity from encoder with Timer Interrupts
« Reply #3 on: June 19, 2015, 12:54:03 pm »
Thanks for your reply.

I am not necessarily stick to this method. If you suggest a better solution it is more than welcome :)



Triggering interrupts from a quadrature encoder output is often not the best way to do things to start with, since contact bounce can trigger many more interrupt than you may be expecting. 

However, if you want to go this way then you could set up a timer and use the encoder output to trigger a timer capture event.  In the capture interrupt you can subtract the previous time from the current time to get the time between interrupts.

Provided you use unsigned math this work correctly even if the timer overflow occurs between two encoder edges, though the maximum possible you can measure is half the timers total period.  This means you will need some scheme to determine if the last time value is invalid.
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26751
  • Country: nl
    • NCT Developments
Re: Velocity from encoder with Timer Interrupts
« Reply #4 on: June 19, 2015, 01:28:51 pm »
Others have posted code to deal with encoders a long time ago. Besides that: never use interrupts from signals unless you are 1000% certain about their maximum rate. In case of an encoder this means either to use polling or proper filtering in the hardware.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline oneeveningTopic starter

  • Newbie
  • Posts: 7
Re: Velocity from encoder with Timer Interrupts
« Reply #5 on: June 19, 2015, 01:52:05 pm »
What is this polling ? Can you elaborate on ?

Others have posted code to deal with encoders a long time ago. Besides that: never use interrupts from signals unless you are 1000% certain about their maximum rate. In case of an encoder this means either to use polling or proper filtering in the hardware.
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26751
  • Country: nl
    • NCT Developments
Re: Velocity from encoder with Timer Interrupts
« Reply #6 on: June 19, 2015, 02:50:42 pm »
Others have posted code to deal with encoders a long time ago. Besides that: never use interrupts from signals unless you are 1000% certain about their maximum rate. In case of an encoder this means either to use polling or proper filtering in the hardware.

If you are concerned about the maximum signal rate, wouldn't polling expose you to lost signals if you didn't poll fast enough? I would have thought if the system can't handle the maximum interupt rate then it couldn't have been design with sufficient capacity.
One of the secret requirements of interrupts is that you have to be able to predict them. External signals without filtering can (and will!) create situations in which you'll get a high number of interrupts which can cause erratic behaviour or even to make the system come to a grinding halt. It is an error often made by novices and software engineers who think a piece of hardware will never fail and is always installed in a laboratory environment.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3233
  • Country: gb
Re: Velocity from encoder with Timer Interrupts
« Reply #7 on: June 19, 2015, 03:19:09 pm »
Triggering interrupts from a quadrature encoder output is often not the best way to do things to start with, since contact bounce can trigger many more interrupt than you may be expecting. 

However, if you want to go this way then you could set up a timer and use the encoder output to trigger a timer capture event.  In the capture interrupt you can subtract the previous time from the current time to get the time between interrupts.

Provided you use unsigned math this work correctly even if the timer overflow occurs between two encoder edges, though the maximum possible you can measure is half the timers total period.  This means you will need some scheme to determine if the last time value is invalid.

you don't need the capture interrupt you'd only need to set the timer for up capture, the captured value
can be read in the pin interrupt

The point is that you wouldn't need two interrupts in either case, you could either handle everything in external interrupt handler handler or in the timer capture interrupt handler.

What is this polling ? Can you elaborate on ?

Polling simply means regularly reading the value of something to look for changes.  You could use a timer interrupt to do this for your encoder.  This means your processor has some overhead all the time, even when the encoder isn't moving.  However, it also means that this overhead is pretty constant, even for fast encoder movements, or with lots of contact bounce etc.
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4067
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: Velocity from encoder with Timer Interrupts
« Reply #8 on: June 19, 2015, 05:37:53 pm »
We actually discussed this earlier.
https://www.eevblog.com/forum/microcontrollers/esp8266-pushbuttons-debounce-how-to-easy-debounce-story/

The only exception I would make for interrupts on user input if the source is an heavily hardware low-pass filtered pushbutton on a ultra low power application.
Interrupts can ruin your day when the knob wears out and starts bouncing all over the place. It also limits the maximum knob speed to the cpu usage, instead of a predetermined polling speed.
You won't notice high cpu usage, but you can easily detect missed polling cycles.
 

Offline oneeveningTopic starter

  • Newbie
  • Posts: 7
Re: Velocity from encoder with Timer Interrupts
« Reply #9 on: June 19, 2015, 09:40:01 pm »
Triggering interrupts from a quadrature encoder output is often not the best way to do things to start with, since contact bounce can trigger many more interrupt than you may be expecting. 

However, if you want to go this way then you could set up a timer and use the encoder output to trigger a timer capture event.  In the capture interrupt you can subtract the previous time from the current time to get the time between interrupts.

Provided you use unsigned math this work correctly even if the timer overflow occurs between two encoder edges, though the maximum possible you can measure is half the timers total period.  This means you will need some scheme to determine if the last time value is invalid.

you don't need the capture interrupt you'd only need to set the timer for up capture, the captured value
can be read in the pin interrupt

The point is that you wouldn't need two interrupts in either case, you could either handle everything in external interrupt handler handler or in the timer capture interrupt handler.


I am not quite sure how can I handle everything with one timer interrupt or input interrupt. Input interrupts, in theory, watching for every pulse from A and B pins of the encoder and make the positive or negative increment. However, here I cannot record a reference sampling period. However, if I only use a timer interrupt, then I cannot catch every encoder pulses.

Where am I wrong ?


What is this polling ? Can you elaborate on ?

Polling simply means regularly reading the value of something to look for changes.  You could use a timer interrupt to do this for your encoder.  This means your processor has some overhead all the time, even when the encoder isn't moving.  However, it also means that this overhead is pretty constant, even for fast encoder movements, or with lots of contact bounce etc.


Here I need to look for changes in a fixed time period. However, I also need to handle the "changes", which has to be handled by another ISR, which is triggered by the encoder pin signal inputs. Otherwise how can I store the changes ?
 

Offline codeboy2k

  • Super Contributor
  • ***
  • Posts: 1836
  • Country: ca
Re: Velocity from encoder with Timer Interrupts
« Reply #10 on: June 19, 2015, 10:31:16 pm »
If you have more than 1 encoder, then look for a software solution. If you only have 1, I'd say do it in hardware and save time trying to write and debug the software.

This EDN design idea provides a direction and count output from a rotary encoder, and increases the count rate when you turn it faster.

http://www.edn.com/design/systems-design/4416528/Adaptive-rotary-encoder-distinguishes-fine-from-coarse

 

Offline oneeveningTopic starter

  • Newbie
  • Posts: 7
Re: Velocity from encoder with Timer Interrupts
« Reply #11 on: June 19, 2015, 10:35:22 pm »
If you have more than 1 encoder, then look for a software solution. If you only have 1, I'd say do it in hardware and save time trying to write and debug the software.

This EDN design idea provides a direction and count output from a rotary encoder, and increases the count rate when you turn it faster.

http://www.edn.com/design/systems-design/4416528/Adaptive-rotary-encoder-distinguishes-fine-from-coarse

Using hardware would definitely be easier but I am also trying to keep the costs low.
 

Offline TerminalJack505

  • Super Contributor
  • ***
  • Posts: 1310
  • Country: 00
Re: Velocity from encoder with Timer Interrupts
« Reply #12 on: June 20, 2015, 03:39:15 am »
Here's some code I wrote while I was doing some informal research on rotary encoder velocity.  The code's still half-baked but it might give you some ideas.  I used an Atmel ATtiny2313--a MCU similar to the one on the Arduino board--for the research.

The strategy I used to determine the velocity was to count the number of "encoder actions" during a fixed sample period.  I then multiplied this by the sample frequency to determine the number of actions per second.  Negative values represented counter-clockwise velocity.  Positive values represented clockwise velocity. 

I used "four phase per click" rotary encoders, so an "encoder action" is the progression of the two channels from "11" -> "01" -> "00" -> "10" -> "11" (clockwise action) or from "11" -> "10" -> "00" -> "01" -> "11" (counter-clockwise action.)  (See the attached FSM diagram.)

The sample period is controlled by a 16-bit variable called 'SampleTick'.  (An 8-bit variable would work as well.)  This variable is incremented by a timer interrupt at a fixed rate.  I played around with different update rates and found rates of 2 Hz to 10 Hz to be ideal.

When the encoder's Update() method runs (the method can be called via polling or via pin change interrupt) it uses SampleTick to determine if it is in the same sample period that it was in when last called or if it is in a new sample period.  If SampleTick is the same as it was when last called then it knows that it is in the same sample period and any new actions are added to a working velocity.  (It's a little more complicated then that since you have to watch out for direction change during a sample period.)

If the Update() method is called and SampleTick has changed from the previous call then a new sample period is started.  In this case, _if_ the two periods are consecutive then the code can use the accumulated encoder actions (aka working velocity) to determine the current velocity.
 

Offline mikerj

  • Super Contributor
  • ***
  • Posts: 3233
  • Country: gb
Re: Velocity from encoder with Timer Interrupts
« Reply #13 on: June 20, 2015, 10:02:45 am »
I am not quite sure how can I handle everything with one timer interrupt or input interrupt. Input interrupts, in theory, watching for every pulse from A and B pins of the encoder and make the positive or negative increment. However, here I cannot record a reference sampling period. However, if I only use a timer interrupt, then I cannot catch every encoder pulses.

Where am I wrong ?

You could trigger a capture interrupt from one of the encoder pins.  Within the interrupt handler you read the state of the other pin, presumably exactly what you are doing now.  However, you also now have a timer value captured, so you can compare the current time to the previous time.

As I and others have said though, using interrupts triggered directly from an encoder with no filitering can be risky.  You could limit the interrupt rate within your code, but that will require an extra timer anyway.

Here I need to look for changes in a fixed time period. However, I also need to handle the "changes", which has to be handled by another ISR, which is triggered by the encoder pin signal inputs. Otherwise how can I store the changes ?

You don't need any ISRs at all with polling since you could do it within your main loop, but it's usually more convenient to set up a timer interrupt to do this.  As for "storing changes", it makes no difference whether you are polling or running off an edge triggered interrupt.   Either you are storing encoder counts in a variable somewhere and polling this value from your main loop, or you are calling a function from your encoder interrupt if the encoder value has changed.  Either method remains exactly the same for a polled solution.
 

Offline oneeveningTopic starter

  • Newbie
  • Posts: 7
Re: Velocity from encoder with Timer Interrupts
« Reply #14 on: June 21, 2015, 05:08:58 pm »
I am not quite sure how can I handle everything with one timer interrupt or input interrupt. Input interrupts, in theory, watching for every pulse from A and B pins of the encoder and make the positive or negative increment. However, here I cannot record a reference sampling period. However, if I only use a timer interrupt, then I cannot catch every encoder pulses.

Where am I wrong ?

You could trigger a capture interrupt from one of the encoder pins.  Within the interrupt handler you read the state of the other pin, presumably exactly what you are doing now.  However, you also now have a timer value captured, so you can compare the current time to the previous time.

As I and others have said though, using interrupts triggered directly from an encoder with no filitering can be risky.  You could limit the interrupt rate within your code, but that will require an extra timer anyway.


Yes, I attached both A and B pins of encoder to same ISR to trigger it. Then I did the necessary bitwise operations to decide either add 1 or subtract 1 from the enc_count variable.

I don't have the encoder setup with me for the time being.
So, my code as follows. I simply take the time at the beginning of the ISR and use this time to compare with actual time to find the time elapsed.

Displacement is always 1 because I am always looking the time elapsed between each encoder ticks.

http://pastebin.com/ZetNMbPi

Am I on the right track ?
 

Offline codeboy2k

  • Super Contributor
  • ***
  • Posts: 1836
  • Country: ca
Re: Velocity from encoder with Timer Interrupts
« Reply #15 on: June 21, 2015, 11:34:54 pm »
I'm jumping in here..

I took a quick look. That code looks reasonable so far.  I don't know about the call to millis() in your ISR.

Code: [Select]
last_time = millis();

Does this work inside the ISR ?  Just a warning to make make sure that it won't be a problem area for you. 

Second, you would be better to get the table lookup first and do something only if it's non-zero. That way you don't call millis() when you don't need to, since it might be a slow operation:

(here's your own code with some of my suggested changes)

Code: [Select]
void encoder()
{
    int8_t direction;
    long this_time, diff;

    enc_val = enc_val << 2;
    enc_val = enc_val | ((PIND & 0b1100) >> 2);
    direction = lookup_table[enc_val & 0b1111];
   
    if (direction) {
        this_time = millis();           // millis() only lasts 50 days and may overflow.
        diff = this_time - last_time;   // you will need to deal with overflow here
        // TODO: set multiplier equal to 1, 2, or 5, for example, depending on time elapsed.
        enc_count = enc_count + direction * multiplier;  // this may go negative , is that OK?
        last_time = this_time;
    }
}

Thirdly, you really should low pass filter your A and B encoder inputs with at least an RC time constant of of around 20-30 ms.  Bounces can cause  100's of singular microsecond changes that can last a total 10-50 ms long. Yes, a fast processor can probably handle the 100k per second (or more!) interrupt rate, but why do that? You really don't want that when most of them will be thrown away, and it will become troublesome when you want to do other things but are hindered by a high interrupt rate caused by switch bounce. This will manifest itself as issues in other areas of your code when you try to rotate the encoder.

A simple RC debouncer on the switches is all you need.

See below.  The horizontal line on the simulation marks the approx. 2.0V CMOS threshold.  Some circuits use a schmitt trigger buffer before going into the microcontroller input pin, but if you can set the micro to use level-triggered interrupts, not edge triggered, then you can just go straight in with this circuit. Many micro's have schmitt trigger inputs anyways.

(note: the diodes are not absolutely necessary -- they help the rise time, and keep the rise time and fall time about the same ... in this example it is about 20-30ms)
« Last Edit: June 21, 2015, 11:42:36 pm by codeboy2k »
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26751
  • Country: nl
    • NCT Developments
Re: Velocity from encoder with Timer Interrupts
« Reply #16 on: June 21, 2015, 11:54:29 pm »
A simple RC debouncer on the switches is all you need.
ONLY IF  the inputs of the microcontroller are of the schmitt-trigger kind which they usually aren't so you'd need to add these in the form of (for example) a 74HC14.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline codeboy2k

  • Super Contributor
  • ***
  • Posts: 1836
  • Country: ca
Re: Velocity from encoder with Timer Interrupts
« Reply #17 on: June 22, 2015, 12:11:20 am »
A simple RC debouncer on the switches is all you need.
ONLY IF  the inputs of the microcontroller are of the schmitt-trigger kind which they usually aren't so you'd need to add these in the form of (for example) a 74HC14.
Yep. I mentioned that too :)  some micros do, some don't have schmitt-trigger inputs.  Bonus if they do.
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26751
  • Country: nl
    • NCT Developments
Re: Velocity from encoder with Timer Interrupts
« Reply #18 on: June 22, 2015, 12:45:56 am »
A simple RC debouncer on the switches is all you need.
ONLY IF  the inputs of the microcontroller are of the schmitt-trigger kind which they usually aren't so you'd need to add these in the form of (for example) a 74HC14.
Yep. I mentioned that too :)  some micros do, some don't have schmitt-trigger inputs.  Bonus if they do.
Schmitt-trigger is a hard requirement! Some microcontrollers have inputs which switch around 0.7V with no hysteresis at all so even a small pulse will flip the input.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline codeboy2k

  • Super Contributor
  • ***
  • Posts: 1836
  • Country: ca
Re: Velocity from encoder with Timer Interrupts
« Reply #19 on: June 22, 2015, 12:59:00 am »
Schmitt-trigger is a hard requirement! Some microcontrollers have inputs which switch around 0.7V with no hysteresis at all so even a small pulse will flip the input.

I agree schmitt trigger is a hard requirement, but many micros have this internally.  If not, then you need it externally.  I mentioned this, perhaps not so clearly.

Plus, which micros will register a logic high at 0.7V input? that's a clear violation of 3.3V CMOS standards where Vt=1.5V and VIH=2.0V.  Perhaps at 2V CMOS or 1.8V CMOS, sure, but that's a different design then :) and I agree there.
 

Offline Jeroen3

  • Super Contributor
  • ***
  • Posts: 4067
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: Velocity from encoder with Timer Interrupts
« Reply #20 on: June 22, 2015, 05:43:11 am »
I've yet to encounter a micro without schmitt triggering. They all seem to have schmitt triggers, as well as ESD HBM diodes.

The voltage level of an IO is not 0.7 by default, its a formula based on the voltage and if the chip is 5V tolerant.
Standard pin minimum high level: 0.41*(VDD-2V)+1.3 V.  At 3.3V = 1.833.
Standard pin maximum low level: 0.28*(VDD-2V)+0.8 V. At 3.3V = 1.164.
With 200 mV schmitt trigger hysteresis.
5V tolerant pins are slightly different.
Read the manual: STM32F103xF
 

Offline oneeveningTopic starter

  • Newbie
  • Posts: 7
Re: Velocity from encoder with Timer Interrupts
« Reply #21 on: June 23, 2015, 10:28:35 am »
Thank you for the thorough answer.

I realised that I do not need to count the ticks, since I am only interested in the elapsed time between each quadrature. So, that would speed up my code a little more. (I am only interested in velocity in one direction)

I tried input interrupt without low pass filter and it was looking fine until I go full speed, which is 2600 RPM with 256 per count encoder resolution.

At that full speed encoder was still reading but there was some value jumps. Delta t (elapsed time between two interrupt calls) was around 12 microsecond and there are some values way greater than it, such as 64520 and 16711688 microseconds.

Tried the low pass filter suggestion.

Calculated the Fc (cut of frequency) as 6.36 Hz by selecting the time constant 25 millisecond = 0.025 second.

Found the R and C values as 240 Ohm and 100uF respectively. Used 220 Ohm instead though.

Now at full speed I don't have those jumps on the delta t value. However, at low speeds I still get delta t of 8 and values around that. Which is totally wrong.

Also I tried the count the number of ticks and realised that with low pass filter, encoder does not read any ticks.

So, what might be the problem ?


I'm jumping in here..

I took a quick look. That code looks reasonable so far.  I don't know about the call to millis() in your ISR.

Code: [Select]
last_time = millis();

Does this work inside the ISR ?  Just a warning to make make sure that it won't be a problem area for you. 

Second, you would be better to get the table lookup first and do something only if it's non-zero. That way you don't call millis() when you don't need to, since it might be a slow operation:

(here's your own code with some of my suggested changes)

Code: [Select]
void encoder()
{
    int8_t direction;
    long this_time, diff;

    enc_val = enc_val << 2;
    enc_val = enc_val | ((PIND & 0b1100) >> 2);
    direction = lookup_table[enc_val & 0b1111];
   
    if (direction) {
        this_time = millis();           // millis() only lasts 50 days and may overflow.
        diff = this_time - last_time;   // you will need to deal with overflow here
        // TODO: set multiplier equal to 1, 2, or 5, for example, depending on time elapsed.
        enc_count = enc_count + direction * multiplier;  // this may go negative , is that OK?
        last_time = this_time;
    }
}

Thirdly, you really should low pass filter your A and B encoder inputs with at least an RC time constant of of around 20-30 ms.  Bounces can cause  100's of singular microsecond changes that can last a total 10-50 ms long. Yes, a fast processor can probably handle the 100k per second (or more!) interrupt rate, but why do that? You really don't want that when most of them will be thrown away, and it will become troublesome when you want to do other things but are hindered by a high interrupt rate caused by switch bounce. This will manifest itself as issues in other areas of your code when you try to rotate the encoder.

A simple RC debouncer on the switches is all you need.

See below.  The horizontal line on the simulation marks the approx. 2.0V CMOS threshold.  Some circuits use a schmitt trigger buffer before going into the microcontroller input pin, but if you can set the micro to use level-triggered interrupts, not edge triggered, then you can just go straight in with this circuit. Many micro's have schmitt trigger inputs anyways.

(note: the diodes are not absolutely necessary -- they help the rise time, and keep the rise time and fall time about the same ... in this example it is about 20-30ms)
« Last Edit: June 23, 2015, 10:30:31 am by oneevening »
 

Offline Bassman59

  • Super Contributor
  • ***
  • Posts: 2501
  • Country: us
  • Yes, I do this for a living
Re: Velocity from encoder with Timer Interrupts
« Reply #22 on: June 25, 2015, 06:05:49 pm »
Tried the low pass filter suggestion.

Calculated the Fc (cut of frequency) as 6.36 Hz by selecting the time constant 25 millisecond = 0.025 second.

Found the R and C values as 240 Ohm and 100uF respectively. Used 220 Ohm instead though.

Now at full speed I don't have those jumps on the delta t value. However, at low speeds I still get delta t of 8 and values around that. Which is totally wrong.

Also I tried the count the number of ticks and realised that with low pass filter, encoder does not read any ticks.

So, what might be the problem ?

I would start by using an oscilloscope to look at the encoder signals at the micro pins.

NB: the 'scope reveals much. I designed something around a Bourns PEC09 encoder with detents, and couldn't understand why the micro was double-incrementing with each turn. It turns out that these particular guys (PEC09-2320F-S0015) has 30 detents but only 15 pulses per rotation, and as you turned it to each detent, first one output would change and then soon the other one would change. It was weird. I ordered some without detents and also the version that has 15 detents instead of 30, and though I haven't tested them yet I think they should step through quadrature as I expect.
 

Offline codeboy2k

  • Super Contributor
  • ***
  • Posts: 1836
  • Country: ca
Re: Velocity from encoder with Timer Interrupts
« Reply #23 on: June 26, 2015, 04:10:46 am »
I would start by using an oscilloscope to look at the encoder signals at the micro pins.

NB: the 'scope reveals much....

That's all I can say too.  Let's see some scope traces at high and low speeds.  I also would not have chosen such a high-value capacitor, as you did. I'm not yet saying that's the problem, but my schematic shows a 0.1uF cap and a few hundred K for the resistors.  When you use a higher cap and lower R it presents the RC circuit with a much lower impedance and draws more charging current from the voltage source, and this might be a problem for you. That's why I chose a higher resistance with lower capacitor for the RC circuit -- it's a much higher impedance load for your supply and charges with much less current requirements from the voltage source.  It may or may not be a problem for you here, but I'm just pointing that out.

Also I tried the count the number of ticks and realised that with low pass filter, encoder does not read any ticks

I don't know what you mean here.  With a low pass filter (and schmitt trigger inputs on your micro) you still get one interrupt for each debounced input.  You can still count these.


 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf