Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16612 Discussions

distance measuring by encoder

Altera_Forum
Honored Contributor II
1,208 Views

I bought an encoder which generate square pulses sig. 

 

i have to stop the engine if arrived to a required distance.  

 

i know that the wheel diameter is 7cm. and the distance is pi*diameter and it equals to 8 pulses counting (1 wheel cycle = 8 pulses counting). 

 

so i thought i have to definfe a cm counter by this way : counter = required_distance/2.75 

 

how can i do that by synthesis way ???  

 

thank you for help...
0 Kudos
6 Replies
Altera_Forum
Honored Contributor II
393 Views

Is yours a single or dual phase encoder? 

Usually encoders have two phases, namely two square pulses signals 90 degrees out of phase. This allows you to know direction, besides distance. 

If this is your case, you may use a standard encoder counter: try browsing opencores.org, search for quadrature encoder/decoder. 

Instead, if you have a single phase encoder, you simply need to count raw pulses.
0 Kudos
Altera_Forum
Honored Contributor II
393 Views

i have one phase encoder ... 

i wrote this program but got an errore about the multiplication, how can i alternate that by synthessisable way ?? 

 

library IEEE; 

use IEEE.std_logic_1164.all; 

use ieee.std_logic_arith.all; 

use ieee.std_logic_unsigned.all; 

 

entity encoder is 

port( 

CLK : in std_logic; 

sig : in std_logic ; 

reset : in std_logic; 

req_dist: buffer std_logic_vector(8 downto 0) -- till 5 meter. 

); 

end entity encoder; 

 

architecture arc_encoder of encoder is 

 

signal tmp_sig : std_logic; 

signal counter : std_logic_vector(8 downto 0); 

signal distance : std_logic_vector(8 downto 0); 

 

begin 

process(CLK)  

begin 

if (reset='1') then 

counter <= (others => '0'); 

else  

distance <= req_dist*24 and "111000000"; ------------------------------------------------------ HERE IS THE ERRORE 

end if; 

 

if rising_edge(sig) then 

if (counter < distance) then 

counter <= counter+1; 

else counter <= counter; 

end if; 

end if; 

end process; 

end architecture arc_encoder;
0 Kudos
Altera_Forum
Honored Contributor II
393 Views

the * function in the std_logic_unsigned library does not allow std_logic_vector to be multiplied by an integer, only another std_logic_vector.

0 Kudos
Altera_Forum
Honored Contributor II
393 Views

Another point - the process is NOT synchronous to the clock because you have not added the "if rising_edge(clk) then" condition to the process.

0 Kudos
Altera_Forum
Honored Contributor II
393 Views

very appriciate your help... thank you very much !

0 Kudos
Altera_Forum
Honored Contributor II
393 Views

Rather than using 

if rising_edge(sig)  

I'd follow Tricky's advice and make everything synchronous to clk. 

Then, sample sig at regular intervals, store in a register and wait for a low to high transition in order to increment counter. 

This would also allow you some filtering to avoid fake counts, which is a common problem with single phase encoders, especially if the rotating wheel is supposed to start and stop.
0 Kudos
Reply