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

Ultrasonic sensor hc-sr04 vhdl code

Altera_Forum
Honored Contributor II
4,005 Views

Hi guys, i found ultrasonic sensor HC-SR04 code implemented in Altera DE2-115 board here https://github.com/rutgers-fpga-projects/ngc-sonar 

My project aims to use the Altera DE2 board with ultrasonic sensor HC-SR04 and I modified the declaration of GPIO expansion header to be suited to Altera DE2. Here's the modified code 

LIBRARY ieee;USE ieee.std_logic_1164.ALL; use ieee.numeric_std.ALL; ENTITY final IS PORT( CLOCK_50 : IN STD_LOGIC; -- 50MHz SW : IN STD_LOGIC_VECTOR(17 DOWNTO 0); KEY : IN STD_LOGIC_VECTOR(3 DOWNTO 0); LEDG : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); LEDR : OUT STD_LOGIC_VECTOR(17 DOWNTO 0); GPIO_0 : INOUT STD_LOGIC_VECTOR(40 DOWNTO 1); -- LCD controller stuff LCD_RS, LCD_EN : OUT STD_LOGIC; LCD_RW : OUT STD_LOGIC; LCD_ON : OUT STD_LOGIC; LCD_DATA : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0) ); END final; ARCHITECTURE arch OF final IS -- convert our 2 digits of hex to 3 digits of BCD FUNCTION to_bcd ( bin : STD_LOGIC_VECTOR(7 DOWNTO 0) ) RETURN STD_LOGIC_VECTOR IS VARIABLE i : integer:=0; VARIABLE bcd : STD_LOGIC_VECTOR(11 DOWNTO 0) := (OTHERS => '0'); VARIABLE bint : STD_LOGIC_VECTOR(7 DOWNTO 0) := bin; BEGIN FOR i IN 0 TO 7 LOOP -- repeating 8 times. bcd(11 DOWNTO 1) := bcd(10 DOWNTO 0); --shifting the bits. bcd(0) := bint(7); bint(7 DOWNTO 1) := bint(6 DOWNTO 0); bint(0) :='0'; IF(i < 7 and bcd(3 DOWNTO 0) > "0100") THEN --add 3 if BCD digit is greater than 4. bcd(3 DOWNTO 0) := STD_LOGIC_VECTOR(UNSIGNED(bcd(3 DOWNTO 0)) + 3); END IF; IF(i < 7 and bcd(7 DOWNTO 4) > "0100") THEN --add 3 if BCD digit is greater than 4. bcd(7 DOWNTO 4) := STD_LOGIC_VECTOR(UNSIGNED(bcd(7 DOWNTO 4)) + 3); END IF; IF(i < 7 and bcd(11 DOWNTO 8) > "0100") THEN --add 3 if BCD digit is greater than 4. bcd(11 DOWNTO 8) := STD_LOGIC_VECTOR(UNSIGNED(bcd(11 DOWNTO 8)) + 3); END IF; END LOOP; RETURN bcd; END to_bcd; -- LCD display controller COMPONENT LCD_Display IS PORT( KEY : IN STD_LOGIC_VECTOR(0 downto 0); CLOCK_50 : IN STD_LOGIC; Hex_Display_Data : IN STD_LOGIC_VECTOR(11 DOWNTO 0); --STD_LOGIC_VECTOR((Num_Hex_Digits*4)-1 DOWNTO 0); LCD_RS, LCD_EN : OUT STD_LOGIC; LCD_RW : OUT STD_LOGIC; LCD_ON : OUT STD_LOGIC; LCD_DATA : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0); inch_cent_switch : IN STD_LOGIC; lds : IN STD_LOGIC_VECTOR(15 DOWNTO 0)); END COMPONENT; SIGNAL graphical_length_display : STD_LOGIC_VECTOR(15 DOWNTO 0); SIGNAL reset: STD_LOGIC; SIGNAL trigger : INTEGER:= 500; -- 10us SIGNAL counter : INTEGER; SIGNAL MAX_CYCLES : INTEGER; -- number of cycles per sample cycle SIGNAL count_dist: INTEGER; -- number of in/cm SIGNAL hex: STD_LOGIC_VECTOR (7 DOWNTO 0); SIGNAL decimal : STD_LOGIC_VECTOR(11 DOWNTO 0); SIGNAL inch_conversion_factor : INTEGER := 7231; SIGNAL cent_conversion_factor : INTEGER := 2847; SIGNAL inch_cent_switch : STD_LOGIC; SIGNAL sample_speed_switch : STD_LOGIC; SIGNAL max_inches : INTEGER := 120; SIGNAL max_centimeters : INTEGER := 300; SIGNAL startcount, elapsed : INTEGER; BEGIN reset <= NOT KEY(1); inch_cent_switch <= SW(0); -- 0 = centimeter, 1 = inch sample_speed_switch <= SW(1); -- set sample rate WITH sample_speed_switch SELECT MAX_CYCLES <= 50000000 WHEN '0', -- 1 sample per second 12500000 WHEN '1'; -- 4 samples per second -- sampling cycle loop -- increments counter variable and resets when sampling cycle is over PROCESS(RESET, CLOCK_50) BEGIN IF reset='1' THEN counter<= 0; ELSIF RISING_EDGE(CLOCK_50) THEN counter <= counter +1; IF(counter > MAX_CYCLES) THEN counter <= 0; END IF; END IF; END PROCESS; -- trigger signal PROCESS(counter) BEGIN IF(counter < trigger) THEN -- 0 to 10us GPIO_0(3) <= '1'; -- trigger ELSE GPIO_0(3) <= '0'; END IF; END PROCESS; -- echo signal listener PROCESS(GPIO_0(1)) BEGIN IF(RISING_EDGE(GPIO_0(1))) THEN startcount <= counter; ELSIF(FALLING_EDGE(GPIO_0(1))) THEN elapsed <= counter - startcount; -- gets length of echo pulse IF(inch_cent_switch = '0') THEN count_dist <= elapsed / cent_conversion_factor; -- convert length in clocks to length in centimeters -- determine bar length for display IF(count_dist > (max_centimeters * 15) / 16) THEN graphical_length_display <= "1111111111111111"; ELSIF(count_dist > (max_centimeters * 14) / 16) THEN graphical_length_display <= "1111111111111110"; ELSIF(count_dist > (max_centimeters * 13) / 16) THEN graphical_length_display <= "1111111111111100"; ELSIF(count_dist > (max_centimeters * 12) / 16) THEN graphical_length_display <= "1111111111111000"; ELSIF(count_dist > (max_centimeters * 11) / 16) THEN graphical_length_display <= "1111111111110000"; ELSIF(count_dist > (max_centimeters * 10) / 16) THEN graphical_length_display <= "1111111111100000"; ELSIF(count_dist > (max_centimeters * 9) / 16) THEN graphical_length_display <= "1111111111000000"; ELSIF(count_dist > (max_centimeters * 8) / 16) THEN graphical_length_display <= "1111111110000000"; ELSIF(count_dist > (max_centimeters * 7) / 16) THEN graphical_length_display <= "1111111100000000"; ELSIF(count_dist > (max_centimeters * 6) / 16) THEN graphical_length_display <= "1111111000000000"; ELSIF(count_dist > (max_centimeters * 5) / 16) THEN graphical_length_display <= "1111110000000000"; ELSIF(count_dist > (max_centimeters * 4) / 16) THEN graphical_length_display <= "1111100000000000"; ELSIF(count_dist > (max_centimeters * 3) / 16) THEN graphical_length_display <= "1111000000000000"; ELSIF(count_dist > (max_centimeters * 2) / 16) THEN graphical_length_display <= "1110000000000000"; ELSIF(count_dist > (max_centimeters * 1) / 16) THEN graphical_length_display <= "1100000000000000"; ELSIF(count_dist > (max_centimeters * 0) / 16) THEN graphical_length_display <= "1000000000000000"; END IF; ELSIF(inch_cent_switch = '1') THEN count_dist <= elapsed / inch_conversion_factor; -- convert length in clocks to length in inches -- determine bar length for display IF(count_dist > (max_inches * 15) / 16) THEN graphical_length_display <= "1111111111111111"; ELSIF(count_dist > (max_inches * 14) / 16) THEN graphical_length_display <= "1111111111111110"; ELSIF(count_dist > (max_inches * 13) / 16) THEN graphical_length_display <= "1111111111111100"; ELSIF(count_dist > (max_inches * 12) / 16) THEN graphical_length_display <= "1111111111111000"; ELSIF(count_dist > (max_inches * 11) / 16) THEN graphical_length_display <= "1111111111110000"; ELSIF(count_dist > (max_inches * 10) / 16) THEN graphical_length_display <= "1111111111100000"; ELSIF(count_dist > (max_inches * 9) / 16) THEN graphical_length_display <= "1111111111000000"; ELSIF(count_dist > (max_inches * 8) / 16) THEN graphical_length_display <= "1111111110000000"; ELSIF(count_dist > (max_inches * 7) / 16) THEN graphical_length_display <= "1111111100000000"; ELSIF(count_dist > (max_inches * 6) / 16) THEN graphical_length_display <= "1111111000000000"; ELSIF(count_dist > (max_inches * 5) / 16) THEN graphical_length_display <= "1111110000000000"; ELSIF(count_dist > (max_inches * 4) / 16) THEN graphical_length_display <= "1111100000000000"; ELSIF(count_dist > (max_inches * 3) / 16) THEN graphical_length_display <= "1111000000000000"; ELSIF(count_dist > (max_inches * 2) / 16) THEN graphical_length_display <= "1110000000000000"; ELSIF(count_dist > (max_inches * 1) / 16) THEN graphical_length_display <= "1100000000000000"; ELSIF(count_dist > (max_inches * 0) / 16) THEN graphical_length_display <= "1000000000000000"; END IF; END IF; END IF; END PROCESS; -- get hex out of integer hex <= STD_LOGIC_VECTOR(TO_UNSIGNED(count_dist, 8)); -- get BCD out of hex decimal <= to_bcd(hex); -- instantiate LCD controller lcd : LCD_Display PORT MAP(KEY(0 DOWNTO 0),CLOCK_50, decimal,LCD_RS, LCD_EN,LCD_RW ,LCD_ON,LCD_DATA, inch_cent_switch, graphical_length_display); END arch; 

So far, this code didn't give error. When downloaded to the board, the LCD only show the unit of measurement not the value of measurement. How to solve it?
0 Kudos
0 Replies
Reply