The following code shows a method of reading a class of sonar rangers.  These rangers requires a trigger pulse.  Shortly after receiving a trigger they transmit a noise pulse and set the echo line high.  When the echo is received the echo line is set low.

SETUP

fritzing diagram




The ranger used is a SRF05 (check the pinouts, there are many variants).

The fritzing diagram shows the back of the ranger, i.e. pin 1 is the rightmost.

Pin 1 is 5V.
Pin 2 is the trigger line.
Pin 3 is the echo line.
Pin 4 is out (unused).
Pin 5 is ground.

photo of set-up

CODE

#include <stdio.h>

#include <pigpio.h>

/*

P1  Name  gpio    used for

 2  5V    ---     5V
 6  GND   ---     Ground
24  CE0   8       Sonar echo
26  CE1   7       Sonar trigger

*/

#define SONAR_TRIGGER 7
#define SONAR_ECHO    8

/* forward prototypes */

void sonarTrigger(void);

void sonarEcho(int gpio, int level, uint32_t tick);

int main(int argc, char *argv[])
{
   if (gpioInitialise()<0) return 1;

   gpioSetMode(SONAR_TRIGGER, PI_OUTPUT);
   gpioWrite  (SONAR_TRIGGER, PI_OFF);

   gpioSetMode(SONAR_ECHO,    PI_INPUT);

   /* update sonar 20 times a second, timer #0 */

   gpioSetTimerFunc(0, 50, sonarTrigger); /* every 50ms */

   /* monitor sonar echos */

   gpioSetAlertFunc(SONAR_ECHO, sonarEcho);

   while (1) sleep(1);

   gpioTerminate();

   return 0;
}

void sonarTrigger(void)
{
   /* trigger a sonar reading */

   gpioWrite(SONAR_TRIGGER, PI_ON);

   gpioDelay(10); /* 10us trigger pulse */

   gpioWrite(SONAR_TRIGGER, PI_OFF);
}

void sonarEcho(int gpio, int level, uint32_t tick)
{
   static uint32_t startTick, firstTick=0;

   int diffTick;

   if (!firstTick) firstTick = tick;

   if (level == PI_ON)
   {
      startTick = tick;
   }
   else if (level == PI_OFF)
   {
      diffTick = tick - startTick;

      printf("%u %u\ ", tick-firstTick, diffTick);
   }
}

BUILD

cc -o sonar sonar.c -lpigpio -lrt -lpthread

RUN

sudo ./sonar >sonar.dat &

While the program is running you can capture the waveform using the notification feature built in to pigpio.  Issue the following commands on the Pi.

pigs no
pig2vcd  </dev/pigpio0 >sonar.vcd &
pigs nb 0 0x180 # set bits for gpios 7 and 8

Move an object in front of the sonar ranger for a few seconds.

pigs nc 0

The file sonar.vcd will contain the captured waveform, which can be viewed using GTKWave.

Overview

LDR waveform 1

Reading circa every 10ms

Sonar waveform 2

One reading, circa 400us

Sonar waveform 3

another

Sonar waveform 4

The file sonar.dat will contain pairs of timestamps and echo length (in us).  The following  script will convert the timestamps into seconds.

awk '{print $1/1000000, $2}' sonar.dat >sonar-secs.dat

Gnuplot is a useful tool to graph data.

plot 'sonar-secs.dat' title 'Sonar'

gnuplot 1
 plot [10:25] 'sonar-secs.dat' title 'Sonar'

gnuplot 1