quadrature Encoder

FPGA projects on this site, or abroad

quadrature Encoder

Postby maldini » Sat Dec 22, 2007 2:31 pm

Hi,

I am trying to create an entity for a quadrature encoder, and I've just realized that I'm short of a major concept in VHDL. My entity as

- 2 inputs (A & B) and
- 1 (inout) for the output (counter counting # of time Encoder goes right/ left).


To know the direction that my encoder has been turned what I would need to do (in pseudo) is analyze both inputs A and B, when A rises then analyze B and if B is up the encoder incremented if B is low the encoder decremented

Then I also need to anayze when A goes down OR when B goes up....Here is the problem..

My process does not allow me to have more than one if ( rising_edge ) As well it does not allow me to have a rising_edge on A and a falling_edge on B. DOES ANYONE KNOW WHY...


Basically what I would want is the following to compile..
*******************************************************
*******************************************************
ENCODER_STATE: process(A)
begin
if ( rising_edge(A) ) then
if ( B = '1' ) then
EncoderValue_OUT <= EncoderValue_OUT + 1;
else
EncoderValue_OUT <= EncoderValue_OUT - 1;
end if;
end if;

if ( falling_edge(A)) then
if ( B = '1' ) then
EncoderValue_OUT <= EncoderValue_OUT + 1;
else
EncoderValue_OUT <= EncoderValue_OUT - 1;
end if;
end if;

end process;
*******************************************************
*******************************************************


FYI: I need to use the output as the counter because I am short in space. I am using a CPLD and have many encoder to "decode" it barely fits.

THE ERROR that I get from the compiler is the following:

Statement is not synthesizable since it does not holds its value under NOT (clock-edge) condition.
maldini
 
Posts: 2
Joined: Mon Jan 22, 2007 4:44 pm

Re: quadrature Encoder

Postby mrand » Wed Jan 02, 2008 6:22 pm

maldini wrote:Hi,

I am trying to create an entity for a quadrature encoder, and I've just realized that I'm short of a major concept in VHDL. My entity as

- 2 inputs (A & B) and
- 1 (inout) for the output (counter counting # of time Encoder goes right/ left).


To know the direction that my encoder has been turned what I would need to do (in pseudo) is analyze both inputs A and B, when A rises then analyze B and if B is up the encoder incremented if B is low the encoder decremented

Then I also need to anayze when A goes down OR when B goes up....Here is the problem..

My process does not allow me to have more than one if ( rising_edge ) As well it does not allow me to have a rising_edge on A and a falling_edge on B. DOES ANYONE KNOW WHY...

Why? Because it is not allowed. Sorry, but that's one of the rules. And these rules typically make sense if you think in terms of hardware... dual-edged flops are basically non-existent in the real world. But there are other ways to perform the same functionality.

It isn't obvious from your description: Are the A and B inputs synchronous to an input clock? Can they both change at the same time, or are they guaranteed to change a different times?

Marc
mrand
 
Posts: 91
Joined: Fri Mar 18, 2005 3:04 am

Postby maldini » Wed Feb 13, 2008 4:19 am

- I do not have a clock.
- A and B cannot change at the same time, they is a large enough gap between the change of A and B.

Is state 1: (Both signals are high)
Turn Right
-> A will go down first
-> B will go down after (clearly after from scope)
-> Now you go to state 2 (both signals are low)
Turn LEFT
-> B will go down first
-> A will go down after (clearly after from scope)
-> Now you go to state 2 (both signals are low)

Is state 2: (Both signals are high)
Turn Right
-> A will go UP first
-> B will go UP after (clearly after from scope)
-> Now you go to state 1 (both signals are HIGH)
Turn LEFT
-> B will go UP first
-> A will go UP after (clearly after from scope)
-> Now you go to state 2 (both signals are HIGH)

thanks,
maldini
 
Posts: 2
Joined: Mon Jan 22, 2007 4:44 pm

Postby Yassen » Thu Feb 14, 2008 11:49 am

Hi,

To decode quadrature signals, you can use a single D-type flip-flop to detect direction and the signals from one channel (or ORring both channels) to count pulses. This is easy - simply attach ch.A to the CLK input and ch.B to the D input or vise versa. But an error might emerge if the rotation changes direction.
Of course, more precise method will be if you quadruple the frequency of ch.A and ch.B - you must build a circuit that counts both on rising and falling edges of each channel.

To your question: as far as I understood you wanted to use simultaneously both rising edges - you cannot do that in a single expression. Instead, if you insist, you can use two consecutive IF statements, assign some variables and than perform an OR of these variables. But that makes no big sense.

You may find useful the Quadrature Decoder project by FPGA4FUN. I think it is very good.

You might also find useful the Rotary Encoder Interface Spartan-3E Starter Kit Xilinx application note for Spartan 3E.

Hope I helped you at least a little.

Good luck,
Yassen
Yassen
 
Posts: 70
Joined: Thu Jun 08, 2006 6:46 pm


Return to General projects