Sonar sensor on the BeagleBone part 1, direct approach

When building a robot one needs to use sensors. I used sonar sensors before for this post:

https://fleshandmachines.wordpress.com/2011/09/16/arduino-double-sonar-with-ros/

The main idea is to get rid of the Arduino on our rover “Scarabeus” and use the sonar sensor directly on the BeagleBone. The problem is that this sensor needs a 5V pulse to trigger ultrasonic output and it also answers with a pulse according to the received incoming signal but all the GPIOs on the BeagleBone operate at 3.3V. There are several possible ways to solve this and I’m presenting two of them here.

  1. Do some electronic hack and apply the sensor directly onto the BeagleBone.
  2. Use a dedicated 5V chip to handle the sensor and communicate via serial port (uart) to the BeagleBone.

This article will describe the first one, the direct approach.

Sonar sensor directly on the BeagleBone

So we have the main issue of voltage levels. It’s a simple task for an electronics guy so it’s clear that I’m not talking about myself 🙂 This problem was solved by Tamás Csibrák. Schematics: And fancy implementation in SMD size:

So far so good. I had to realize that even though the BeagleBone has lot of libraries (and 2 especially nice ones) implementing an Arduino-style hardware interface they still all lack the pulseIn() function.

http://arduino.cc/en/Reference/pulseIn

So in order to have something like this I checked which existing library is more rich and I chose PyBBIO as my target of expanding. Here’s how it looks like:

def pulseIn(gpio_pin, value, timeout=23200):
  """ pulseIn by Bence Magyar. """
  """ timeout default value represents 400 cm sonar distance signal length. """
  """ Returns length of chosen signal in microseconds. """
  assert (gpio_pin in GPIO), "*Invalid GPIO pin: '%s'" % gpio_pin
  assert (value in [HIGH, LOW]), "*Invalid value parameter: '%d'" % value
  endSig = value
  startSig = LOW if value==HIGH else HIGH
  start = micros()
  while digitalRead(gpio_pin) == startSig and (micros()-start) < timeout:       delayMicroseconds(30)   if micros()-start > timeout:
    return timeout
  start = micros()
  while digitalRead(gpio_pin) == endSig and (micros()-start) < timeout:
      delayMicroseconds(30)
  return micros() - start

Notes: The Python code above is not performing really well with the timing so because of this the measured distances are not really precise and the usable range of the sensor is limited. To solve this I’m planning to try a C++ implementation.

Video:

References:

http://www.nathandumont.com/node/250

http://www.gigamegablog.com/2012/01/22/beaglebone-coding-101-using-the-serial-and-analog-pins/

http://electricstitches.com/blog/2012/03/22/xbee-beaglebone-communication/

https://github.com/maxpowel/BeagleBone-Tools

https://github.com/alexanderhiam/PyBBIO

Advertisements

5 thoughts on “Sonar sensor on the BeagleBone part 1, direct approach

  1. I’ve been doing a lot of work with the Beaglebone and Beagleboard recently and honestly, the Linux kernel has not been so great with sensors requiring real time response. I wrote some kernel drivers to handle a sonar and I’m still having poor results. This is mainly because of the handling time of interrupts, for they are not handled when they happen, but rather they are put on a queue to be executed. I haven’t tried real time extensions yet, but servicing time is currently terrible. I’m continuing researching solutions, but honestly I think the best bet is to use the programmable realtime units on the beaglebone (some kind of built in microcontroller core, and there are a pair of them. The subsystem is called “pruss”).

  2. You could probably manage this using the eCAP modules, which are capable of timestamping transitions with 10 ns resolution. You can also synchronize two and configure one to generate a pulse while the other timestamps the response.

    I recently made a small proof-of-concept example showing that direct access to peripherals is possible even with straight python code, allowing the full potential of peripherals to be exploited without having to depend on the features you need having been implemented in kernel drivers: https://github.com/mvduin/py-uio … It is still in a rough state but hopefully it’ll evolve to something usable by non-wizards 😉

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s