PING))) Ultrasonic Distance Sensor

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:

Thanks for any insight.

JT

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;
    }
}

}
}[/code]