0

I am working with the LV-MaxSonar EZ2 and a Raspberry Pi 3 model B. As you know, The Raspberry Pi can not read analog input, that's why I used an ADC (analog to digital converter), an MCP3008 to convert the analog-volt to a digital input for the the raspberry. I followed this tutorial : https://github.com/alx-s/RPi_tutorials/tree/master/Analog_inputs-MaxBotix
The code :

#!/usr/bin/env python  
import time  
import os  
import RPi.GPIO as GPIO  

# GPIO  
GPIO.setmode(GPIO.BCM)  
DEBUG = 1  


# read SPI data from MCP3008 chip, 8 possible adc's (0 thru 7)
def readadc(adcnum, clockpin, mosipin, misopin, cspin):
        if ((adcnum > 7) or (adcnum < 0)):
                return -1
        GPIO.output(cspin, True)

        GPIO.output(clockpin, False) # start clock low
        GPIO.output(cspin, False) # bring CS low

        commandout = adcnum
        commandout |= 0x18 # start bit + single-ended bit
        commandout <<= 3 # we only need to send 5 bits here
        for i in range(5):
                if (commandout & 0x80):
                        GPIO.output(mosipin, True)
                else:
                        GPIO.output(mosipin, False)
                commandout <<= 1
                GPIO.output(clockpin, True)
                GPIO.output(clockpin, False)

        adcout = 0
        # read in one empty bit, one null bit and 10 ADC bits
        for i in range(12):
                GPIO.output(clockpin, True)
                GPIO.output(clockpin, False)
                adcout <<= 1
                if (GPIO.input(misopin)):
                        adcout |= 0x1

        GPIO.output(cspin, True)

        adcout >>= 1 # first bit is 'null' so drop it
        return adcout

# change these as desired - they're the pins connected from the
# SPI port on the ADC to the RPi
SPICLK = 18
SPIMISO = 23
SPIMOSI = 24
SPICS = 25

# set up the SPI interface pins
GPIO.setup(SPIMOSI, GPIO.OUT)
GPIO.setup(SPIMISO, GPIO.IN)
GPIO.setup(SPICLK, GPIO.OUT)
GPIO.setup(SPICS, GPIO.OUT)

# ultrasonic sensor connected to adc #0
ultrasonic_adc_0 = 0;

try:
        while True:

            distance_0 = readadc(ultrasonic_adc_0, SPICLK, SPIMOSI,      SPIMISO, SPICS)
            print "distance 0:", distance_0     

            # hang out and do nothing
            # depending on the sensor the reading cycle might happen every 50ms or 100ms
        time.sleep(0.05)

except KeyboardInterrupt:
        GPIO.cleanup()

Wiring the MCP3008 to the RPI :

  • VDD -> 3.3V
  • VREF -> 3.3V
  • AGND -> GND
  • CLK -> GPIO 18
  • DOUT -> GPIO 23
  • DIN -> GPIO 24
  • CS -> GPIO 25
  • DGND -> GND

Wiring the sensor :

  • sensor's GND -> GND
  • sensor's 5V -> 5V
  • sensor's AN -> MCP3008's ch0 (pin 0)

After running the script, I got a logical output. However, there was an error rate that grows with the distance between the sensor and the object. The following examples explain that :

An object that is 16 cm away from the sensor ----> the output is 21 cm
An object that is 17 cm away from the sensor ----> the output is 21 cm
An object that is 18 cm away from the sensor ----> the output is 21 cm
An object that is 19 cm away from the sensor ----> the output is 24 cm
An object that is 35 cm away from the sensor ----> the output is 42 cm
An object that is 56 cm away from the sensor ----> the output is 66 cm & 67cm
An object that is 70 cm away from the sensor ----> the output is 84 cm
An object that is 84 cm away from the sensor ----> the output is 96 cm

I also tried the library of MCP3008 developed by Adafruit using this command : sudo pip install adafruit-mcp3008 and I run this code :

import time

# Import SPI library (for hardware SPI) and MCP3008 library.
import Adafruit_GPIO.SPI as SPI
import Adafruit_MCP3008
# Software SPI configuration:
CLK  = 18
MISO = 23
MOSI = 24
CS   = 25
mcp = Adafruit_MCP3008.MCP3008(clk=CLK, cs=CS, miso=MISO, mosi=MOSI)
while True:
               values[0] = mcp.read_adc(0)
               print "the distance is : ", values, 'cm"
time.sleep(0.5)

And I got the same errors as with the first code.

Since I got these errors, I decided to try Arduino.
At first, I used an Arduino Nano, and followed the tutorial in published by Maxbotix in their website , link : https://www.maxbotix.com/Arduino-Ultrasonic-Sensors-085/

Since the Arduino Nano does not contain Pwm pins, I used the Analog-Volt code for a single sensor from the same website (Maxbotix website) and I followed the whole tutorial. The results that I got were closer than with the Raspberry Pi, but they were not precise:

An object that is 30 cm away from the sensors ----> the output is 27.84 cm
An object that is 25 cm away from the sensors ----> the output is 22.94 cm

Since the results were not precise, I decided to use an Arduino Uno this time. I used both the Pwm and the Analog-Volt and I got the same error rate as with the Arduino Nano.

I even tried different sensors, but I got the same errors.

So please, If you have any advices or recommendations about this problem, please mention them. Thank you.

4
  • 1
    I see no evidence that the code you use properly reads the module. Could you post the code you are using and explain how you have wired the module.
    – joan
    Feb 22, 2018 at 12:09
  • @joan I updated the post adding to it the code and how I wired the sensor and the MCP3008 wit hthe RPi.
    – singrium
    Feb 22, 2018 at 14:14
  • Could you explain what the ADC is returning and how it is used? It certainly does not return a value in centimeters which seems to be what the code is assuming.
    – joan
    Feb 22, 2018 at 16:39
  • @joan, as I read, the MCP takes an analog input and convert it to digital output. In this case, the digital output is sent to the RPi to be displayed. But in the link where I took the code from, he said that we can get the distance as a direct output, without any additional processing for the output (As I understood, The MCP gives as a digital output the distance, which is really weird because there is nothing in the code that confirms this). I will take a look on how the MCP3008 works and what are the operations that it does with the analog value to convert it to a digital output.
    – singrium
    Feb 23, 2018 at 8:29

1 Answer 1

1

From memory the sensor returns a reading of Vcc/512 per inch. I take that to mean it returns 512 inches if the ADC reading is 1023 (the maximum).

So inches = (ADC * 512) / 1023

The code you use seems to make the gross assumption that there are two centimeters per inch, in fact there are 2.54 centimeters per inch.

So centimeters = (ADC * 512 * 2.54) / 1023

Or centimeters = ADC * 1.27

Unfortunately this doesn't help at all, if anything it will make the readings worse if your results are to be believed.

You need to check that you are using 3V3 for Vcc and Vref. That may be the source of the confusion.

3
  • As you said, this does not help. The measurements are still wrong even after that. I made sure that the VCC and Vref are wired to 3.3 Volt pins
    – singrium
    Feb 23, 2018 at 14:19
  • @singrium ...and the sensor needs to be powered from 3V3. If the sensor is powered from 5V the readings will be 5/3.3 or 1.52 times too high (at least).
    – joan
    Feb 23, 2018 at 16:44
  • I did many tests, applied the calculations you mentioned, and it seems to work properly. Thank you so much.
    – singrium
    Feb 26, 2018 at 9:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.