Forum Discussion
HC-SR04 (ultrasonic sensor) verilog code help
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 :(12 Replies
- Altera_Forum
Honored Contributor
With what part do you need help. The more specific you can put your question, the easier it is to give a statisfying answer.
- Altera_Forum
Honored Contributor
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. - Altera_Forum
Honored Contributor
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 - Altera_Forum
Honored Contributor
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 - Altera_Forum
Honored Contributor
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] - Altera_Forum
Honored Contributor
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.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 - Altera_Forum
Honored Contributor
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? - Altera_Forum
Honored Contributor
--- 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? - Altera_Forum
Honored Contributor
A devision by two is the same as shifting to the LSB side.
- Altera_Forum
Honored Contributor
--- 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?