Skip to content

Commit

Permalink
Added sonar ranger examples.
Browse files Browse the repository at this point in the history
  • Loading branch information
joan2937 committed Nov 20, 2020
1 parent 8b1d345 commit 8ada8c3
Show file tree
Hide file tree
Showing 8 changed files with 594 additions and 3 deletions.
Binary file modified DOC/dbase/lg.sqlite
Binary file not shown.
43 changes: 43 additions & 0 deletions DOC/src/defs/examples.def
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,17 @@ E.g.

./rotary_encoder 2 7 5 # gpiochip 2, gpioA 7, gpioB 5

?4|sonar_ranger.c|2020-11-20|Sonar Ranger
Code to find the distance between a sonar ranger and the nearest object. The code assumes the sonar ranger is the type with separate trigger and echo lines.

./sonar_ranger [chip] trigger echo

E.g.

./sonar_ranger 20 21 # gpiochip 0, trigger 20, echo 21

./sonar_ranger 2 7 5 # gpiochip 2, trigger 7, echo 5

?4|tx_pulse.c|2020-11-18|Tx Pulse
Demonstrates usage of the tx pulse function.

Expand Down Expand Up @@ -107,6 +118,17 @@ E.g.

./rotary_encoder.py 2 7 5 # gpiochip 2, gpioA 7, gpioB 5

?4|sonar_ranger.py|2020-11-20|Sonar Ranger
Code to find the distance between a sonar ranger and the nearest object. The code assumes the sonar ranger is the type with separate trigger and echo lines.

./sonar_ranger.py [chip] trigger echo

E.g.

./sonar_ranger.py 20 21 # gpiochip 0, trigger 20, echo 21

./sonar_ranger.py 2 7 5 # gpiochip 2, trigger 7, echo 5

?4|testbed.py|2020-11-18|Testbed
Exercises SPI, I2C, and serial links with miscellaneous hardware.

Expand Down Expand Up @@ -171,6 +193,16 @@ E.g.

./rotary_encoder 2 7 5 # gpiochip 2, gpioA 7, gpioB 5

?4|sonar_ranger.c|2020-11-20|Sonar Ranger
Code to find the distance between a sonar ranger and the nearest object. The code assumes the sonar ranger is the type with separate trigger and echo lines.

./sonar_ranger [chip] trigger echo

E.g.

./sonar_ranger 20 21 # gpiochip 0, trigger 20, echo 21

./sonar_ranger 2 7 5 # gpiochip 2, trigger 7, echo 5

?4|tx_pulse.c|2020-11-18|Tx Pulse
Demonstrates usage of the tx pulse function.
Expand Down Expand Up @@ -231,6 +263,17 @@ E.g.

./rotary_encoder.py 2 7 5 # gpiochip 2, gpioA 7, gpioB 5

?4|sonar_ranger.py|2020-11-20|Sonar Ranger
Code to find the distance between a sonar ranger and the nearest object. The code assumes the sonar ranger is the type with separate trigger and echo lines.

./sonar_ranger.py [chip] trigger echo

E.g.

./sonar_ranger.py 20 21 # gpiochip 0, trigger 20, echo 21

./sonar_ranger.py 2 7 5 # gpiochip 2, trigger 7, echo 5

?4|testbed.py|2020-11-18|Testbed
Exercises SPI, I2C, and serial links with miscellaneous hardware.

Expand Down
6 changes: 3 additions & 3 deletions EXAMPLES/lgpio/chipline.c
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
/*
bench.c
chipline.c
2020-11-18
Public Domain
http://abyz.me.uk/lg/lgpio.html
gcc -Wall -o bench bench.c -llgpio
gcc -Wall -o chipline chipline.c -llgpio
./bench
./chipline
*/
#include <stdio.h>

Expand Down
140 changes: 140 additions & 0 deletions EXAMPLES/lgpio/sonar_ranger.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/*
sonar_ranger.c
2020-11-20
Public Domain
http://abyz.me.uk/lg/lgpio.html
gcc -Wall -o sonar_ranger sonar_ranger.c -llgpio
./sonar_ranger [chip] trigger echo
E.g.
./sonar_ranger 20 21 # ping gpiochip 0, trigger 20, echo 21
./sonar_ranger 2 7 5 # gpiochip 2, trigger 7, echo 5
*/

#include <stdio.h>
#include <stdlib.h>

#include <lgpio.h>

int pinged = 0;
uint64_t ping_time;

void cbf(int e, lgGpioAlert_p evt, void *userdata)
{
int i;
static uint64_t _high = 0;

for (i=0; i<e; i++)
{
if (evt[i].report.level == 1) _high = evt[i].report.timestamp;
else
{
if (_high != 0)
{
ping_time = evt[i].report.timestamp - _high;
_high = 0;
pinged = 1;
}
}
}
}

float readRanger(int h, int trigger)
{
double start;

/*
Return the distance in cms if okay, otherwise 0.
*/

pinged = 0;

/* send a 15 microsecond high pulse as trigger */
lgTxPulse(h, trigger, 15, 0, 0, 1);

start = lguTime();

while (!pinged)
{
if ((lguTime() - start) > 0.3) return 0.0;
lguSleep(0.01);
}

return 17015.0 * ping_time / 1e9;
}

int main(int argc, char *argv[])
{
int h;
int chip, trigger, echo;
int cb_echo;
int err;

if (argc == 4) /* chip trigger echo */
{
chip = atoi(argv[1]);
trigger = atoi(argv[2]);
echo = atoi(argv[3]);
}

else if (argc == 3) /* trigger echo (chip 0) */
{
chip = 0;
trigger = atoi(argv[1]);
echo = atoi(argv[2]);
}

else
{
fprintf(stderr, "Usage: ./sonar_ranger [chip] trigger echo\n");
return -1;
}

h = lgGpiochipOpen(chip);

if (h < 0)
{
fprintf(stderr, "can't open /dev/gpiochip%d (%s)\n",
chip, lgErrStr(h));
return -1;
}

err = lgGpioClaimOutput(h, 0, trigger, 0);

if (err < 0)
{
fprintf(stderr, "can't claim GPIO %d (%s)\n",
trigger, lgErrStr(err));
return -1;
}

err = lgGpioClaimAlert(h, 0, LG_BOTH_EDGES, echo, -1);

if (err < 0)
{
fprintf(stderr, "can't claim GPIO %d (%s)\n",
echo, lgErrStr(err));
return -1;
}

err = lgGpioSetAlertsFunc(h, echo, cbf, NULL);

if (err < 0)
{
fprintf(stderr, "can't create callback for GPIO %d (%s)\n",
echo, lgErrStr(cb_echo));
return -1;
}

while (1)
{
printf("cms=%.1f\n", readRanger(h, trigger));
lguSleep(0.2);
}
}

127 changes: 127 additions & 0 deletions EXAMPLES/py_lgpio/sonar_ranger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
#!/usr/bin/env python
"""
sonar_ranger.py
2020-11-20
Public Domain
http://abyz.me.uk/lg/py_rgpio.html
./sonar_ranger.py [chip] trigger echo
chip specifies a gpiochip number. gpio is a GPIO in the previous
gpiochip (gpiochip0 if there is no previous gpiochip).
e.g.
./sonar_ranger.py 1 24 25 # ping gpiochip1: trigger 24, echo 25
./sonar_ranger.py 24 25 # ping gpiochip0: trigger 24, echo 25
"""

import time
import lgpio

class ranger:
"""
This class encapsulates a type of acoustic ranger. In particular
the type of ranger with separate trigger and echo pins.
A pulse on the trigger initiates the sonar ping and shortly
afterwards a sonar pulse is transmitted and the echo pin
goes high. The echo pins stays high until a sonar echo is
received (or the response times-out). The time between
the high and low edges indicates the sonar round trip time.
"""

def __init__(self, sbc, chip, trigger, echo):
"""
The class is instantiated with the SBC to use, the gpiochip,
and the GPIO connected to the trigger and echo pins.
"""
self._sbc = sbc
self._chip = chip
self._trigger = trigger
self._echo = echo

self._ping = False
self._high = None
self._time = None

self._handle = sbc.gpiochip_open(chip)

sbc.gpio_claim_output(self._handle, trigger)

sbc.gpio_claim_alert(self._handle, echo, sbc.BOTH_EDGES)

self._cb = sbc.callback(self._handle, echo, sbc.BOTH_EDGES, self._cbf)

self._inited = True

def _cbf(self, chip, gpio, level, tick):
if level == 1:
self._high = tick
else:
if self._high is not None:
self._time = tick - self._high
self._high = None
self._ping = True

def read(self):
"""
Return the distance in cms if okay, otherwise 0.
"""
if self._inited:
self._ping = False
# send a 15 microsecond high pulse as trigger
self._sbc.tx_pulse(self._handle, self._trigger, 15, 0, 0, 1)
start = time.time()
while not self._ping:
if (time.time()-start) > 0.3:
return 0
time.sleep(0.01)
return 17015 * self._time / 1e9
else:
return None

def cancel(self):
"""
Cancels the ranger and returns the gpios to their
original mode.
"""
if self._inited:
self._inited = False
self._cb.cancel()
self._sbc.gpio_free(self._chip, self._trigger)
self._sbc.gpio_free(self._chip, self._echo)
self._sbc.gpiochip_close(self._chip)
if __name__ == "__main__":

import sys
import time
import lgpio as sbc
import sonar_ranger

if len(sys.argv) == 4: # chip trigger echo
chip = int(sys.argv[1])
trigger = int(sys.argv[2])
echo = int(sys.argv[3])

elif len(sys.argv) == 3: # trigger echo (chip 0)
chip = 0
trigger = int(sys.argv[1])
echo = int(sys.argv[2])

else:
print("Usage: ./sonar_ranger.py [chip] trigger echo")
exit()

ranger = sonar_ranger.ranger(sbc, chip, trigger, echo)

try:
while True:
print("cms={:.1f}".format(ranger.read()))
time.sleep(0.2)
except KeyboardInterrupt:
pass

ranger.cancel()

Loading

0 comments on commit 8ada8c3

Please sign in to comment.