neilkeron
Posts: 4
Joined: Sun Jun 17, 2018 6:04 am

Reading 4 Analog ultrasonic sensors with MCP 3008

Mon Jun 18, 2018 1:13 am

Hello everyone,
New to this site so I'm not even sure if this is the right place to ask a question. I am trying to read the analogue output from 4 ultrasonic sensors via an MCP3008. The sensors are connected to channels 4, 5, 6 & 7 of the MCP3008 so I am interrogating them sequentially with python3 code. I can do this successfully using bit banging with the following code:

Code: Select all

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
However I would like to minimise the time between reading subsequent sensors so I am trying to use SPI. I have installed the spi tools. When I interrogate the MCP3008 with the following code, I get null outputs:

Code: Select all

import RPi.GPIO as GPIO
import spidev
import time
import os
import itertools
import math
import sys
from time import sleep
from collections import deque

# Open SPI bus
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz=1000000


Thisfilename = os.path.basename(__file__)
GPIO.setmode(GPIO.BCM)
##UT_triggerUL = 17 #upper left green/black external cable, yellow internal)
UT_triggerUR = 21 #upper right
##UT_triggerLL = 4  #lower left
##UT_triggerLR = 26  #lower right

#Initialise some variable which are inside timed loops
timeFirstReflection = 0
timeFirstReflectionLL = 0
timeStartPing = 0
whilecounter = 0
trycounter = 0

DEBUG = 0
DEBUG2 = 0
DEBUG3 = 1
DEBUG4 = 1
start1 = 1
VoltInc = 1000 #increment to detect ping
VoltInc2 = 150 #increment to detect first echo
VoltIncLL = 100
VoltIncLR = 100
VoltDec = 50	
dAvDistUR = deque(maxlen=10)
dAvDistUR = [100]*10
dAvDistUL = deque(maxlen=10)
dAvDistUL = [100]*10
dAvDistLL = deque(maxlen=10)
dAvDistLL = [100]*10
dAvDistLR = deque(maxlen=10)
dAvDistLR = [100]*10
sleeptime = 0.01
ping = 0.00002 #ping duration in micro seconds
DistOffset = -1 #correction for distance in corner cube reflector
#corrections for length of towbar
ULcorrection = 0#124.1
URcorrection = 0#125.3
LLcorrection = 0#124.1
LRcorrection = 0#125.3

C = 61 #half width of car in cms
T = 60 #half width of trailer in cms
pi = 3.1415927

SoS = 34200 #centimetres per second
##print ("Hi Neil")
#Set up two deques, one to hold the last two values of measured voltage and one to hold the last two values of time. (This deque is used for each measurement ie UL, UR, LL, LR)
dVolts = deque(maxlen=2)
#now fill it with starting values
dVolts = [950] * 2
dTime = deque(maxlen=2)
dTime = [0]*2
dVoltsLL = deque(maxlen=2)
dVoltsLL = [0]*2
#open a file for the results
if DEBUG3:
	myVOLTfileUR = open("myVOLTSUR.txt","w")
	print ("Name of this file: ",Thisfilename," Name of text file: ", myVOLTfileUR.name)
	myVOLTfileUL = open("myVOLTSUL.txt","w")
	print ("Name of this file: ",Thisfilename," Name of text file: ", myVOLTfileUL.name)
	myVOLTfileLR = open("myVOLTSLR.txt","w")
	myVOLTfileLL = open("myVOLTSLL.txt","w")

# read SPI data from MCP3008 chip, channel 2 (8 possible adc's (0 thru 7))
def readadc(adcnum):
	spi.open(0, 0)
	adc = spi.xfer2([1,(8+adcnum)<<4,0])
	print ("adc = ",adc)
	data = ((adc[1] & 3) << 8) + adc[2]
	return data
Output from print("adc = ",adc) gives me 'adc = [0, 0, 0]

When I run sudo ./spidev_test -D /dev/spidev0.0, with the MOSI and MISO pins connected together, after an initial start up I get the correct response: viz:-
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)

FF FF FF FF FF FF
40 00 00 00 00 95
FF FF FF FF FF FF
FF FF FF FF FF FF
FF FF FF FF FF FF
DE AD BE EF BA AD
F0 0D



but when I reconnect MOSI & MISO to the MCP3008, run my code (and get zero results) and then reconnect MOSI and MISO to each other and run spidev_test, I get
spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)

00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00 00 00 00 00
00 00

If anyone can shed any light on what is happening, I would be eternally grateful.

Thanks & Regards
Neil Keron

pcmanbob
Posts: 4465
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Analog sensor with MCP 3008 output 0

Mon Jun 18, 2018 9:35 am

Please edit your post and add code tags, as it stands your code is missing ail its indentation and so it un testable by anyone.

Add [code] at the top

code goes here

and [/code] at the bottom.
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

User avatar
mahjongg
Forum Moderator
Forum Moderator
Posts: 11030
Joined: Sun Mar 11, 2012 12:19 am
Location: South Holland, The Netherlands

Re: Analog sensor with MCP 3008 output 0

Mon Jun 18, 2018 10:21 am

Split off from original thread, as this was a hijack, and added code tags.

User avatar
DougieLawson
Posts: 34167
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website

Re: Reading 4 Analog ultrasonic sensors with MCP 3008

Mon Jun 18, 2018 11:17 am

Have you thought about using the supplied function in GPIOZero which makes reading an MCP3008 into child's play?

Code: Select all

#!/usr/bin/python3
from gpiozero import MCP3008
from time import sleep
LL = MCP3008(channel=4, device=0)

while True:
    adcValue = (LL.value * 3.3)*100
    print('{:.1f}'.format(adcValue), 10 * ' ')
    sleep(0.1)
That's with the MCP3008 wired on the standard hardware spi0.0 pins (GPIO9, GPIO10, GPIO11 & GPIO08).
Microprocessor, Raspberry Pi & Arduino Hacker
Mainframe database troubleshooter
MQTT Evangelist
Twitter: @DougieLawson

2012-18: 1B*5, 2B*2, B+, A+, Z, ZW, 3Bs*3, 3B+

Any DMs sent on Twitter will be answered next month.

pcmanbob
Posts: 4465
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Reading 4 Analog ultrasonic sensors with MCP 3008

Mon Jun 18, 2018 2:33 pm

So assuming you have the MCP3008 connected correctly

for ref.
VDD (Pin 16) wire this to 3.3V
VREF (Pin 15) wire this to 3.3V
AGND (Pin 14) wire this to ground
CLK (Pin 13) wire this to GPIO11 (Pin 23/SCLK)
DOUT (Pin 12) wire this to GPIO9 (Pin 21/MISO)
DIN (Pin 11) wire this to GPIO10 (Pin 19/MOSI)
CS (Pin 10) wire this to GPIO8 (Pin 24/CE0)
DGND (Pin 9) wire this to GROUND

try running this code, it should return all 8 input values and so prove your MCP3008 / pi are communicating correctly.

Code: Select all

#!/usr/bin/python
 
import spidev
import time

#Create SPI
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz=1000000
 
def readadc(adcnum):
    # read SPI data from the MCP3008, 8 channels in total
    if adcnum > 7 or adcnum < 0:
        return -1
    r = spi.xfer2([1, 8 + adcnum << 4, 0])
    data = ((r[1] & 3) << 8) + r[2]
    return data


print('Reading MCP3008 values, press Ctrl-C to quit...')
# Print nice channel column headers.
print('| {0:>4} | {1:>4} | {2:>4} | {3:>4} | {4:>4} | {5:>4} | {6:>4} | {7:>4} |'.format(*range(8)))
print('-' * 57)
# Main program loop.
while True:
    # Read all the ADC channel values in a list.
    values = [0]*8
    for i in range(8):
        # The read_adc function will get the value of the specified channel (0-7).
        data = readadc(i)
        values[i] = round (data * (3.3/1023.0), 2)
    # Print the ADC values.
    print('| {0:>4} | {1:>4} | {2:>4} | {3:>4} | {4:>4} | {5:>4} | {6:>4} | {7:>4} |'.format(*values))
    # Pause for half a second.
    time.sleep(0.5)
    
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

neilkeron
Posts: 4
Joined: Sun Jun 17, 2018 6:04 am

Re: Reading 4 Analog ultrasonic sensors with MCP 3008

Thu Jun 21, 2018 12:29 am

Many thanks to all for your helpful replies.
I thought I might have fried my MCP3008 soldering it in to a Pi hat so I have been to Jaycar and bought a brand new one and am now testing it on a breadboard. I have run the code that pcmanbob kindly posted and stepped a 3.3v input through each input channel in turn. The results (below) shows the 3.3 output on each channel but I am confused as to why the other channels are all giving random results. Should I be pulling all the channels down to ground? If so, can you suggest what resistance I should use.
Kind regards
Neil Keron
Reading MCP3008 values, press Ctrl-C to quit...
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---------------------------------------------------------
| 3.3 | 0.12 | 0.13 | 0.14 | 0.15 | 0.18 | 0.25 | 0.39 |
| 3.3 | 0.23 | 0.24 | 0.25 | 0.27 | 0.31 | 0.4 | 0.62 |
| 3.3 | 0.3 | 0.31 | 0.33 | 0.35 | 0.4 | 0.51 | 0.78 |
| 3.3 | 0.46 | 0.46 | 0.47 | 0.48 | 0.51 | 0.57 | 0.66 |
| 3.3 | 0.49 | 0.47 | 0.46 | 0.45 | 0.45 | 0.41 | 0.25 |
| 3.3 | 0.29 | 0.29 | 0.27 | 0.24 | 0.2 | 0.12 | 0.0 |
| 3.3 | 0.31 | 0.1 | 0.03 | 0.0 | 0.0 | 0.0 | 0.0 |
| 3.3 | 0.03 | 0.02 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 3.29 | 0.24 | 0.09 | 0.03 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0.0 | 0.0 | 0.03 | 0.03 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0.02 | 0.05 | 0.06 | 0.07 | 0.11 | 0.2 | 0.35 | 0.46 |
| 0.56 | 3.3 | 0.59 | 0.45 | 0.53 | 0.7 | 0.86 | 1.06 |
| 0.95 | 3.3 | 0.78 | 0.73 | 0.75 | 0.74 | 0.78 | 1.09 |
| 0.94 | 3.3 | 0.75 | 0.75 | 0.68 | 0.65 | 0.65 | 1.05 |
| 0.6 | 3.3 | 0.51 | 0.44 | 0.3 | 0.15 | 0.0 | 0.0 |
| 0.04 | 3.3 | 0.25 | 0.15 | 0.05 | 0.0 | 0.0 | 0.0 |
| 0.03 | 3.3 | 0.16 | 0.14 | 0.07 | 0.01 | 0.0 | 0.0 |
| 0.1 | 3.3 | 0.06 | 0.04 | 0.03 | 0.02 | 0.0 | 0.0 |
| 0.0 | 3.3 | 0.24 | 0.02 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0.1 | 0.14 | 0.15 | 0.16 | 0.16 | 0.25 | 0.49 | 0.91 |
| 0.84 | 0.46 | 3.3 | 0.59 | 0.61 | 0.75 | 0.84 | 1.06 |
| 0.9 | 0.56 | 3.3 | 0.74 | 0.78 | 0.75 | 0.77 | 1.03 |
| 0.89 | 0.65 | 3.3 | 0.8 | 0.73 | 0.69 | 0.69 | 1.01 |
| 0.61 | 0.49 | 3.3 | 0.57 | 0.43 | 0.26 | 0.03 | 0.0 |
| 0.0 | 0.2 | 3.3 | 0.23 | 0.08 | 0.0 | 0.0 | 0.0 |
| 0.11 | 0.19 | 3.3 | 0.2 | 0.14 | 0.1 | 0.0 | 0.0 |
| 0.1 | 0.2 | 0.21 | 0.18 | 0.11 | 0.02 | 0.0 | 0.15 |
| 0.0 | 0.02 | 0.04 | 0.01 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 0.0 | 0.0 | 0.06 | 3.3 | 0.07 | 0.05 | 0.21 | 0.58 |
| 0.51 | 0.29 | 0.25 | 3.3 | 0.42 | 0.56 | 0.77 | 0.89 |
| 0.88 | 0.64 | 0.5 | 3.3 | 0.74 | 0.79 | 0.75 | 0.72 |
| 0.88 | 0.68 | 0.51 | 3.3 | 0.73 | 0.77 | 0.71 | 0.64 |
| 0.79 | 0.65 | 0.68 | 3.3 | 0.79 | 0.51 | 0.31 | 0.0 |
| 0.38 | 0.45 | 0.4 | 3.3 | 0.4 | 0.21 | 0.0 | 0.0 |
| 0.0 | 0.2 | 0.23 | 0.22 | 0.14 | 0.04 | 0.0 | 0.0 |
| 0.0 | 0.13 | 0.15 | 0.15 | 0.1 | 0.01 | 0.0 | 0.0 |
| 0.0 | 0.0 | 0.05 | 0.22 | 3.3 | 0.12 | 0.0 | 0.0 |
| 0.0 | 0.0 | 0.0 | 0.06 | 3.3 | 0.04 | 0.0 | 0.0 |
| 0.0 | 0.0 | 0.0 | 0.02 | 3.3 | 0.0 | 0.0 | 0.0 |
| 0.02 | 0.04 | 0.04 | 0.08 | 3.3 | 0.18 | 0.32 | 0.71 |
| 0.64 | 0.39 | 0.34 | 0.29 | 3.3 | 0.56 | 0.73 | 0.85 |
| 0.88 | 0.59 | 0.52 | 0.43 | 3.3 | 0.75 | 0.8 | 0.75 |
| 0.88 | 0.74 | 0.71 | 0.72 | 0.73 | 0.74 | 0.75 | 0.73 |
| 0.86 | 0.71 | 0.68 | 0.68 | 0.67 | 0.65 | 0.57 | 0.35 |
| 0.5 | 0.45 | 0.43 | 0.45 | 0.49 | 3.3 | 0.37 | 0.0 |
| 0.0 | 0.12 | 0.14 | 0.18 | 0.22 | 3.3 | 0.15 | 0.0 |
| 0.0 | 0.03 | 0.05 | 0.1 | 0.16 | 3.3 | 0.09 | 0.0 |
| 0.0 | 0.0 | 0.0 | 0.02 | 0.11 | 3.3 | 0.04 | 0.0 |
| 0.0 | 0.0 | 0.0 | 0.0 | 0.07 | 3.3 | 0.02 | 0.0 |
| 0.0 | 0.0 | 0.0 | 0.0 | 0.03 | 3.3 | 0.0 | 0.0 |
| 0.0 | 0.0 | 0.0 | 0.0 | 0.01 | 0.05 | 0.14 | 0.39 |
| 0.36 | 0.22 | 0.21 | 0.24 | 0.28 | 0.35 | 0.51 | 0.86 |
| 0.83 | 0.46 | 0.43 | 0.43 | 0.42 | 0.42 | 3.3 | 0.95 |
| 0.87 | 0.74 | 0.71 | 0.73 | 0.72 | 0.62 | 3.3 | 0.95 |
| 0.85 | 0.68 | 0.65 | 0.65 | 0.65 | 0.63 | 3.3 | 0.5 |
| 0.64 | 0.39 | 0.36 | 0.35 | 0.32 | 0.31 | 3.3 | 0.19 |
| 0.0 | 0.06 | 0.06 | 0.05 | 0.06 | 0.21 | 3.3 | 0.0 |
| 0.0 | 0.12 | 0.14 | 0.14 | 0.15 | 0.17 | 3.3 | 0.0 |
| 0.0 | 0.08 | 0.09 | 0.09 | 0.06 | 0.02 | 0.0 | 0.0 |
| 0.0 | 0.04 | 0.05 | 0.04 | 0.02 | 0.0 | 0.0 | 0.0 |
| 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.12 | 3.3 |
| 0.0 | 0.0 | 0.0 | 0.0 | 0.01 | 0.02 | 0.04 | 3.3 |
| 0.15 | 0.18 | 0.18 | 0.19 | 0.2 | 0.22 | 0.24 | 3.3 |
| 0.38 | 0.21 | 0.2 | 0.2 | 0.21 | 0.21 | 0.18 | 3.3 |
| 0.65 | 0.34 | 0.31 | 0.32 | 0.32 | 0.32 | 0.27 | 3.3 |
^CTraceback (most recent call last):
File "test3008.py", line 35, in <module>
time.sleep(0.5)
KeyboardInterrupt

pcmanbob
Posts: 4465
Joined: Fri May 31, 2013 9:28 pm
Location: Mansfield UK

Re: Reading 4 Analog ultrasonic sensors with MCP 3008

Thu Jun 21, 2018 8:33 am

If you just leave all the unused inputs on your MCP3008 un connected they are just floating with no set input, so you will see random voltages on them.

If you don't need to use a particular input you can just connect it to ground then you should see a voltage near zero.
Remember we want information.......................no information no help
The use of crystal balls & mind reading is not supported

neilkeron
Posts: 4
Joined: Sun Jun 17, 2018 6:04 am

Re: Reading 4 Analog ultrasonic sensors with MCP 3008

Thu Jun 21, 2018 12:11 pm

That makes sense. Thanks

neilkeron
Posts: 4
Joined: Sun Jun 17, 2018 6:04 am

Re: Reading 4 Analog ultrasonic sensors with MCP 3008

Fri Jun 22, 2018 7:21 am

Dear All
Finally cracked it.
Previously when bit banging from arbitrary pins I was setting the GPIO, viz:
GPIO.setup(SPIMOSI, GPIO.OUT)
GPIO.setup(SPIMISO, GPIO.IN)
GPIO.setup(SPICLK, GPIO.OUT)
GPIO.setup(SPICS, GPIO.OUT)

When using SPI, this is not required and if you leave it in, it messes up the MCP3008 for subsequent SPI reads.

Thanks to everyone for your help. Hope I'm competent enough one day to return the compliment for someone.

Regards
Neil Keron

Return to “Troubleshooting”