We have upgraded the community system as part of the upgrade a password reset is required for all users before login in.

How to Interface an HC-SR04 Sonar sensor to the Omega2



  • The Omega2 cannot interface to the HC-SR04 Sonar sensor using the same technique that the Arduino uses. This is due to the Linux OS running on the Omega2 whereas the Arduino does not run an OS.

    The HC-SR04 works by sensing a high-to-low transition on its Trig input and then emitting an ultrasonic ‘ping’. When the ‘ping’ is emitted the Echo output goes high. When the reflection of the ‘ping’ is heard by the sensor the Echo output is driven low. Timing how long the Echo output was high for is the key to using the sensor.

    In order to get accurate timing of the Echo output, hardware must be used. Software timing will be inaccurate due to the Linux OS.

    The Omega2 does have SPI hardware. SPI is a synchronous serial protocol. SPI is basically a shift register. During an SPI transaction, data is shifted out on one edge of the clock signal and shifted in on the other edge. To interface the HC-SR04, the SPI port is used to capture the Echo output as the input (MISO) to the SPI port. This way the clock rate of the SPI port will determine the sample rate or resolution of the timing. The lowest speed clock rate for the SPI on the Omega2 is 50KHz or 20 uS per bit. The SPI hardware of the Omega2 has a 16 byte internal buffer. 16 bytes yields 128 bits of timing data. In other words, using the SPI port you can time an event that is a maximum of 2.56mS with 20uS resolution.

    Sound travels at about 0.034cm/s at sea level. Appling this to the HC-SR04 interfaced to the SPI port yields a best case of 0.68cm/bit. This has to be cut in half because the time is the time for the ‘ping’ to go out and come back. So 0.34cm/bit. The 16 byte SPI buffer yields 128 bits so the best case distance is 43.51cm. The best case is never achieved due to a delay in the HC-SR04 between when Trig is detected low and Echo goes high.

    The accuracy of this interface technique is dependant on the SPI clock time. The 50KHz clock yields 0.68cm/bit. Increasing the SPI clock speed would yield better accuracy, however, due to the 16 byte buffer limitation, doubling the clock speed would halve the maximum distance.

    The maximum distance can be increased by using DMA or an interrupt to move data out of the hardware SPI buffer and into memory. Then a longer transaction can be used. Currently the SPI driver in the Omega2 does not support DMA or interrupt. If you want to send or receive more than 16 bytes you must use multiple transaction instead of one long transaction. Due to the delays introduced between transactions it is impractical to use multiple transactions and expect to have accurate timing.

    Bottom line, you can interface an HC-SR04 to an Omega2 using the SPI port. The limitations are that the accuracy will be 0.68cm and the maximum distance will be around 35cm (about a foot). If and when the SPI driver is updated to use DMA or interrupts to allow for longer transactions then longer distances and greater accuracy can be achieved.

    The Python code below demonstrates the feasibility of this technique. One more thing, the HC-SR04 is a 5V device. To avoid destroying your Omega2 you will need someway to translate the 5V Echo output to 3.3V used by the Omega2 GPIO. The simplest is to use a voltage divider consisting of a 1K resistor and a 2.2K resistor. The IK is wired to the Echo output. The other end is wired to the 2.2K resistor. The other end of the 2.2K resistor is wired to Gnd. The junction of the two resistors is wired to GPIO pin 9 of the Omega2.

    #!/usr/bin/python

    #Python script to demonstrate using the SPI port of an Omega2 to interface an
    #HC-SR04 Sonar sensor.

    #Author: James R. Behrens
    #1-30-2018

    #Running Firmware 0.1.10 b160

    #limited to 16 bytes per transfer
    #minimum clock rate is 50KHz

    #This works out to a distance of about 30 cm !!!
    #It could read out further if the SPI transfer could go 32 bytes without
    #introducing any delays.

    #Speed of sound is .034 cm/uS
    #Time per sample is 20uS
    #Distance per sample is .034 cm/Us * 20uS => .68 cm per bit
    #Resolution is 0.68 cm
    #Distance is (number of high bits * 0.68) / 2 or high bits * 0.34

    #How it works
    #The CS1 output goes low at the start of the SPI transfer, this drives the Trig
    #input low which tells the HC-SR04 to emit a 'ping'. Meanwhile, the SPI port is
    #sampling the Echo input of the HC-SR04 every 20uS. The data is stored in a list
    #of bytes. At the end of the SPI transfer, the list is processed to find out
    #how many consecutive high bits there are. Multiply by 0.38 and you have the
    #distance in cm.

    #This works because the SPI uses hardware, so the Linux OS cannot interfere with
    #the timing. Longer distances could be read if DMA could be used to move the
    #data into memory or the clock could be slowed down. Lowering the clock speed
    #decrease the resolution, so better solution is to enable SPI DMA transfers.

    #CS1 - GPIO6 -> Trig
    #SCLK - GPIO7
    #MOSI - GPIO8
    #MISO - GPIO9 -> Echo

    #The HC-SR04 is a 5V device. You must use a voltage divider or some other means
    #of isolating the Echo signal to prevent it from killing the Omega's GPIO pin.
    #A 1K and 2K resistor wired in series with the Echo output with the 2k resistor
    #wired to Gnd. The junction of the two resistors is wired to MISO (GPIO 9).

    import onionSpi

    spi = onionSpi.OnionSpi(1, 32766)

    spi.speed = 50000

    spi.registerDevice();
    print spi.checkDevice()

    spi.setupDevice()

    #read 128 bits from the SPI port
    values = spi.readBytes(0, 16)

    print values

    count = 0
    #determine the number of consecutive high bits
    for b in values:
    if b != 0:
    if b == 255:
    count = count + 8
    else:
    #determine number of high bits
    x = b
    c = 8
    while c > 0:
    c = c - 1
    if x & 0x01 == 0x01:
    count = count + 1
    x = x >> 1

    distance = count * 0.34
    print 'Distance: {}cm'.format(str(distance))

    [0_1517338133203_sonar.py](Uploading 100%)



  • Errrr, couldn't you utilize: https://onion.io/store/arduino-dock-r2/ ?

    It seems that you would then get the maximum response from your sonar, and then shuttle the data from the arduino chip one to the omega. For around $25 (20 for the dock, and around 4-5 for the sensor) you could get this done much in the same way you have before, without having to depend on linux timing being a bit inadequate for the task.


Log in to reply
 

Looks like your connection to Community was lost, please wait while we try to reconnect.