Alchitry Forums
PING))) Ultrasonic Distance Sensor - Printable Version

+- Alchitry Forums (https://forum.alchitry.com)
+-- Forum: Alchitry (https://forum.alchitry.com/forum-1.html)
+--- Forum: General Questions (https://forum.alchitry.com/forum-2.html)
+--- Thread: PING))) Ultrasonic Distance Sensor (/thread-248.html)



PING))) Ultrasonic Distance Sensor - john.tilghman@protonmail.com - 08-26-2020

I am trying to see if anyone has used the PING))) Ultrasonic Distance Sensor before.

It has some interesting timing to be able to use it, as well as it's triggered as well as the return echo come back on the same pin.

PING))) Ultrasonic Distance Sensor I have a lot of these to drive and a AVR just bogs down the more you put on.

From the website:
Quote:Interfacing to a microcontroller is a snap. A single I/O pin is used to trigger an ultrasonic burst (well above human hearing) and then "listen" for the echo return pulse. The sensor measures the time required for the echo return, and returns this value to the microcontroller as a variable-width pulse via the same I/O pin.


Thanks for any insight.

JT


RE: PING))) Ultrasonic Distance Sensor - alchitry - 08-26-2020

I've used one of these a long time ago when I was first starting to mess with electronics with the "BASIC Stamp" but I haven't used one with an FPGA.

It should be pretty easy to make it work though. 

Here's a module I just wrote. I haven't tested it but it should be a good starting point.

Code:
module ping #(
   CLK_FREQ = 100000000 : CLK_FREQ > 0,
   MAX_PULSE_TIME = 19000000 : MAX_PULSE_TIME > 0, // 19000000ns aka 19ms
   TRIGGER_PULSE_TIME = 5000 : TRIGGER_PULSE_TIME < MAX_PULSE_TIME && TRIGGER_PULSE_TIME > 0, // the trigger pulse duration
   DELAY_TIME = 250000 : DELAY_TIME < MAX_PULSE_TIME && DELAY_TIME > 0 // the time between measurements
 )(
   input clk,  // clock
   input rst,  // reset
   inout ping,
   output count[$clog2(CLK_FREQ * MAX_PULSE_TIME / 1000000000)],
   output valid
 ) {
 
 const TRIGGER_PULSE_CYCLES = CLK_FREQ * TRIGGER_PULSE_TIME / 1000000000;
 const DELAY_CYCLES = CLK_FREQ * DELAY_TIME / 1000000000;
 
 .clk(clk) {
   .rst(rst) {
     fsm state = {SEND_PULSE, WAIT_RISE, WAIT_FALL, WAIT};
     dff counter[count.WIDTH];
     dff sync[3];
   }
 }
 
 always {
   valid = 0;
   count = counter.q;
   
   ping.enable = 0; // don't drive the output by default
   ping.write = 1; // default to 1
   
   sync.d = c{sync.q[1:0], ping.read}; // synchronize the ping input to the clock
   
   case (state.q) {
     state.SEND_PULSE:
       ping.enable = 1; // drive the output
       counter.d = counter.q + 1;
       if (counter.q == TRIGGER_PULSE_CYCLES-1) {
         counter.d = 0;
         state.d = state.WAIT_RISE;
       }
     state.WAIT_RISE:
       if (sync.q[2:1] == 2b01) { // rising edge
         state.d = state.WAIT_FALL;
       }
     state.WAIT_FALL:
       counter.d = counter.q + 1;
       if (sync.q[2:1] == 2b10) { // falling edge
         state.d = state.WAIT;
         valid = 1; // output the count
         counter.d = 0;
       }
     state.WAIT:
       counter.d = counter.q + 1;
       if (counter.q == DELAY_CYCLES-1) {
         counter.d = 0;
         state.d = state.SEND_PULSE;
       }
   }
 }
}