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

HC-SR04 (ultrasonic sensor) verilog code help

Altera_Forum
Honored Contributor II
10,143 Views

Hi, for my project i have to interface the HC-SR04 (ultrasonic sensor) to my DE2-115 board. I have been struggling with the verilog code for a while. Can anyone please help me out with the code? 

The sensor basically needs to tell me how far an object is and report back stating the distance measured also.  

I understand that the distance can be found by distance= speed of sound X time duration and i've looked at the HC-SR04 manual for timing of the pulses. 

 

Please help :(
0 Kudos
12 Replies
Altera_Forum
Honored Contributor II
5,294 Views

With what part do you need help. The more specific you can put your question, the easier it is to give a statisfying answer.

0 Kudos
Altera_Forum
Honored Contributor II
5,294 Views

Hi Mao, 

 

Base on the HC-SR04 (ultrasonic sensor) timing diagram the control signal is trig and echo pulse width. I could suggest you design a state machine to generate the trig pulse with counter. Use the Echo trig to calculate the pulse and cover to distance.
0 Kudos
Altera_Forum
Honored Contributor II
5,294 Views

Hello, thanks for your comment. Sorry if i wasn't precise. Let me explain what i exactly want to do with it. I want to measure the how far an object is from the sensor and if an object is detected i want a LED to light up and also a variable "dist" should give me the calculated distance of the object. I read the manual. but i am confused about timings. I am not sure if i am getting it right.  

 

Here is the vhdl code for the sensor (i don't know vdhl but took some ideas from here): 

 

https://github.com/xesscorp/xula/blob/master/fpga/xula_lib/hcsr04.vhd 

 

Here's the verilog code I've written so far (i'm sure I'm missing a lot): 

timescale 1 us/ 1 us  

 

module sensor (trig, dist, clear, led, clk, echo); 

 

 

output trig, dist, clear, led; 

input clk, echo; 

 

reg [3:0] timer; 

reg [3:0] dist; 

 

always @ (posedge clk) 

begin 

timer <= timer +1; //timer will start soon as positive clock pulse is detected 

if timer = 10; //It takes 10 us to send pulse from sensor 

trig = 1; //then,trig is high after 10us 

else if echo; //when echo is high, dist counting starts, trig goes to low, led turns on 

begin 

dist <= dist + 1; //echo pulse width 

trig <= 0;  

led = 1; 

end 

if dist <= 38; //max echo back time = 38 us without obstacles 

begin //then everything will be back to initial condition 

clear =1; 

dist <= 0; 

timer <=0; 

led <= 0; 

end 

end 

 

assign dist = dist * 340; //multiplying with speed of sound in air 

 

endmodule
0 Kudos
Altera_Forum
Honored Contributor II
5,295 Views

Hi, i took help from a vhdl code (i am not familiar with it though). Here's the link to the vhdl code: 

 

https://github.com/xesscorp/xula/blob/master/fpga/xula_lib/hcsr04.vhd 

 

I know i'm missing something. I am a verilog beginner. Hope you can help. 

 

Here's the code I've written so far: 

 

'timescale 1 us/ 1 us  

 

module sensor (trig, dist, clear, led, clk, echo); 

 

 

output trig, dist, clear, led; 

input clk, echo; 

 

reg [3:0] timer; 

 

always @ (posedge clk) 

begin 

timer <= timer +1; //timer will start soon as positive clock pulse is detected 

if timer = 10; //It takes 10 us to send pulse from sensor 

trig = 1; //then,trig is high after 10us 

else if echo; //when echo is high, dist counting starts, trig goes to low, led turns on 

begin 

dist <= dist + 1; //echo pulse width 

trig <= 0;  

led = 1; 

end 

if dist <= 38; //max echo back time = 38 us without obstacles 

begin //then everything will be back to intial condition 

clear =1; 

dist <= 0; 

timer <=0; 

led <= 0; 

end 

end 

 

assign dist = dist * 340; //multiplying with speed of sound in air 

 

endmodule
0 Kudos
Altera_Forum
Honored Contributor II
5,295 Views

First, please post your code between code tags. Second, what is your clock speed 500 kHz? I myself cannot write Verilog, only read it with effort, but it seems your basic idea is ok. 

 

[edit]Oh, and aside from using code tags, please use indentations. [/edit]
0 Kudos
Altera_Forum
Honored Contributor II
5,295 Views

module usensor (trig, echo, distance, reset, clk); output trig, distance; input clk, echo, reset; reg dist_counter=0; reg counter=0; always @ (posedge clk) begin if (reset) begin counter<=0; distance<=0; end else begin counter <= counter + 1; if (counter <= 500) //10usec to initialize sensor begin echo<=0; trig<=1; // trig is set high end if (echo) // sensing 5v at echo pin so echo pin is high begin dist_counter <= dist_counter + 1; trig <=0; end if (counter<= 1900000) // maximum time of sensing any object is 38ms begin echo<=0; trig<=0; end if (counter<= 5000000) // wait 1 sec to begin again begin counter<=0; distance <=0; end end end assign distance = (dist_counter ** (-1)) * 340; // speed of sound in air endmodule  

 

 

I have made a few modifications to the code. I think this one seems more logical. But i have 9 errors while compiling. Please help. 

I think it says i cannot assign value to trig and echo.
0 Kudos
Altera_Forum
Honored Contributor II
5,295 Views

If you can post the errors as well we can help you better. 

And I don't know much about verilog but isn't <= a VHDL thing, and does Verilog use assign?
0 Kudos
Altera_Forum
Honored Contributor II
5,295 Views

 

--- Quote Start ---  

If you can post the errors as well we can help you better. 

And I don't know much about verilog but isn't <= a VHDL thing, and does Verilog use assign? 

--- Quote End ---  

 

 

Well i have gotten no compilation errors now (had to fix a few here and there) but now the problem is i need to write a synthesizable code. I'm not sure if u have that kind of thing in VHDL.  

N yes Verilog uses assign and "<=" is an unblocking statement for verilog which basically means "=". 

 

Coming back to the synthesizable part,  

 

assign distance_o = (dist_counter * 340/2) 

 

I cant use division. How else can i do this?
0 Kudos
Altera_Forum
Honored Contributor II
5,295 Views

A devision by two is the same as shifting to the LSB side.

0 Kudos
Altera_Forum
Honored Contributor II
5,295 Views

 

--- Quote Start ---  

A devision by two is the same as shifting to the LSB side. 

--- Quote End ---  

 

 

Thank you. So, I will have to Left shift it by 1 (Ex: A/2 is the same as A<<1). Example, 4'd12, in binary its 4'b1100; if we right shift it once we get 4'b0110 which is 6 in decimal.  

 

I think that is correct.  

 

Can you please correct me if i'm wrong. Multiplication operator is synthesizable right?
0 Kudos
Altera_Forum
Honored Contributor II
5,295 Views

As far as I know both multiply and devide are, but devision in one clock cycle needs a big area. It is possible that your FPGA has not enoug space left for that.

0 Kudos
Altera_Forum
Honored Contributor II
5,295 Views

Yea division doesn't work on Xilinx or Altera, from my experience. But multiplication works. Just wanted to confirm it. I think i have an idea of what to do now. Thanks so much :D

0 Kudos
Reply