PDA

View Full Version : How to get encoder direction and speed / rpm ? ( with DT INT ?)



luminas
- 22nd September 2013, 15:19
Is there any simple way (minimum code) to get encoder direction and speed / rpm , not position ?

Encoder is incremental type , output are A,B,Z

I am thinking about using DT INT , but not sure where to start .

Could any one point me which direction to go ? Thank you :)

HenrikOlsson
- 22nd September 2013, 15:51
Hi,
Since you're not interested in position one simple way would be to count pulses from one channel for a certain amount of time. The direction could then be determined by polling channel B at the rising edge of channel A - or the other way around. What kind of speeds we're talking about. A couple of 100Hz or several 100kHz or even more? What else is the PIC going to do?

Which PIC are you using? If you haven't decided on one yet then one option is to have a look at the 18F2431 series, it's got a quadrature encoder interface peripheral.

/Henrik.

luminas
- 22nd September 2013, 16:05
Thank Henrik !

I am planning to use 16F88 , but I will look at 18F2431 as your suggestion

As for the speed , it just 0 - 10 rpm max , with 100 count encoder.

The pic will then output led indicator direction and speed low - med - high according to rpm , that simple :)

HenrikOlsson
- 22nd September 2013, 16:14
Oh, in that case there's no need for the 18F2431, it would be overkill.
Set one of the PICs timers up as a counter and feed the pulses from one channel to it, then read its value at precise intervals and you have the velocity. Or use the Count command to Count pulses for a certian amount of time. Or, instead of counting pulses, use the capture module to measure the length of ONE pulse. Or use PulsIn to do the same thing, or.....

/Henrik.

luminas
- 22nd September 2013, 16:23
Hahaha, yes indeed 18F2431 would be overkill :)

Okay, the issue with rpm is clearer now, but what about direction ?

HenrikOlsson
- 22nd September 2013, 16:29
Like I said earlier, read the state of channel B at the rising edge of channel A and you have the direction.

luminas
- 22nd September 2013, 16:39
Like I said earlier, read the state of channel B at the rising edge of channel A and you have the direction.

i am not quite clear about it, is it something like this ? :

porta =00000001 direction is clockwise
porta =00000010 direction is counter clockwise

what happen with the direction WHILE the encoder is rotating ? wouldn't it be changing constantly ?

HenrikOlsson
- 22nd September 2013, 16:53
The two signals are 90 degrees out of phase in relation to each other. This is what it looks like:
7090
When the encoder is rotating "forward" (ie you're going left to right in the above picture) channel B is low at the rising edge of channel A. When the encoder is rotating "backwards" (ie you're going right to left in the above picture) channel B is high at the rising edge of channel A. So, you need to detect when channel A goes from low to high and then read channel B.

WHILE ChannelA_Input = 1 : WEND ' Wait for channel A to go low if it happens to be high
WHILE ChannelA_Input = 0 : WEND ' Now wait for the rising edge of channel A
Direction = ChannelB_Input ' If channel B is high we're moving in one direction, if it's low we're moving in the other
The above code obviosuly presents a risk of hanging if the velocity happens to be 0 or very low but you get the idea.

/Henrik.

luminas
- 22nd September 2013, 17:02
The above code obviosuly presents a risk of hanging if the velocity happens to be 0 or very low but you get the idea.


I thought about that , but I worried about DT-INT would block it in the process

is it possible to put this in-line with speed detecting process ?

luminas
- 26th September 2013, 17:03
I can find direction with this code:

A tied to portb.4
B tied to portb.5

Direction = portb.5 ^ portb.4
lcdout $FE,1,DEC(Direction)


but, the reading is NOT consistent , if I turn clockwise , Direction is not always 1 ( well , most of the time it is 1 ) and vice versa

any tips anyone ?

HenrikOlsson
- 26th September 2013, 17:24
When doing it like that you don't "where" in the cycle you are reading the inputs.
Since you're basically first reading one input then the other it's possible for "the other" input to change state from what it actually was when you read the first input.

Try something like

Temp = PortB
Direction = Temp.5 ^ Temp.4

This will insure that both bits are sampled at exactly the same time.

/Henrik.

Dick Ivers
- 27th September 2013, 20:29
Sorry to be so dumb, but I don't see how XOR'ing A and B produces a direction signal. When I try it on paper I get a new signal at double the frequency??

richard
- 27th September 2013, 21:30
rotary encoders woes are a common issue have a look at this thread


http://www.picbasic.co.uk/forum/showthread.php?t=13177

secondly if your encoder is mechanical type contact bounce is an issue that must be dealt with

Ioannis
- 27th September 2013, 22:22
Also at this PIC:

http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en010291

It has Qudrature Encoder Interface and hardware filters too!

Ioannis