1
\$\begingroup\$

I recently posted, but my schematic changed and so did my problem.

I have this set up and on my raspberry Pi I have this code running which gets the 10-bit number from the ADC and converts it into a usable voltage for me.

#!/usr/bin/python

import spidev
import time
import os

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

# Function to read SPI data from MCP3002 chip
# Channel must be an integer 0-7
def ReadChannel(channel):
  adc = spi.xfer2([1,(8+channel)<<4,0])
  data = ((adc[1]&3) << 8) + adc[2]
  return data

# Function to convert data to voltage level,
# rounded to specified number of decimal places.
def ConvertVolts(data,places):
  volts = (data * 5) / float(1023)
  volts = round(volts,places)
  return volts

while True:

  # Read the MCP3002
  ADC_volts = ReadChannel(0)
  digital_Volts = ConvertVolts(ADC_volts,2)
  print digital_Volts

schematic

simulate this circuit – Schematic created using CircuitLab

enter image description here

The problem I am having is that if I run this I expect to get a constant 3.3V reading in my program. However, I do not. I get a fluctuating reading between 4.34-4.63V. I need to establish a constant voltage because I intend to include a piezo element to detect voltage from vibrations and the signal needs to be biased to get both the pos+ and neg- voltages produced.

Can anyone explain why I don't get 3.3V, and why I don't get a constant 4.5 or near abouts reading but a fluctuating value? Thank you

\$\endgroup\$
  • \$\begingroup\$ Have you used a multimeter (or preferably an oscilloscope) to measure the voltage at the output of the MCP601? \$\endgroup\$ – stefandz Oct 2 '15 at 12:34
  • \$\begingroup\$ I don't have an oscilloscope at home, but I measure it to be 3.26V with my multimeter \$\endgroup\$ – JamesDonnelly Oct 2 '15 at 13:32
  • \$\begingroup\$ Then you'll be wanting to follow @ScottSeidman's advice below. \$\endgroup\$ – stefandz Oct 2 '15 at 13:33
  • 1
    \$\begingroup\$ The flucuations are probably the result of using a power rail as the ADC reference. That needs to be a dedicated reference like an LM4040. \$\endgroup\$ – Matt Young Oct 2 '15 at 13:45
  • \$\begingroup\$ If I used a 5V voltage regulator, would that have the same result? \$\endgroup\$ – JamesDonnelly Oct 2 '15 at 13:56
4
\$\begingroup\$

After verifying that your input voltage is what you think it is, I suggest looking directly at what's in adc[1] and adc[2], and making sure what's in there looks like what you expect.

The best way to do this kind of stuff is to use a scope or logic analyzer to look directly at the SPI bus.

If you compare figure 6-1 in the MCP3008 datasheet (the chip the user you took code from is using) to figure 5-1 for the MCP3002 chip you're using, you'll see that the 3008 requires one more bit to be clocked in on the DIN line than the 3002 does. It's very likely that you need to modify your spi.xfer call to reflect this.

You need to read up on these communication protocols in the respective datasheets, try to understand what values your call " adc = spi.xfer2([1,(8+channel)<<4,0])" is sending out on the Din line, and modify appropriately.

First glance, "adc = spi.xfer2([1,13<<3,0])" will work to give you a single ended read on CH0 if you want MSB to shift out first, or "adc = spi.xfer2([1,12<<3,0])" if you need the LSB first, but I don't know exactly how spi.xfer2 works, and I've only glanced at the data sheets.

\$\endgroup\$
  • \$\begingroup\$ Can you explain what you mean by what's in adc[1] and adc[2]? I only have 1 ADC, the other is an Op-amp? \$\endgroup\$ – JamesDonnelly Oct 2 '15 at 13:55
  • 1
    \$\begingroup\$ You're running a program, and it has variables in it. One of those variables appears to be an array called adc, and it is being used in the calculation of your display. \$\endgroup\$ – Scott Seidman Oct 2 '15 at 14:48
  • 1
    \$\begingroup\$ @JamesDonnelly that person is using a different chip, from the same family, but with a slightly different communication protocol. \$\endgroup\$ – Scott Seidman Oct 2 '15 at 15:34
  • 3
    \$\begingroup\$ @JamesDonnelly: You're in much better hands with Scott on this :-) Just wanted to point out that there's a web page detailing the minor programming differences between MCP3002 and MCP3008. Cheers! \$\endgroup\$ – Fizz Oct 2 '15 at 17:00
  • 1
    \$\begingroup\$ Oops, I was off one bit! Shift 3 instead of 4. \$\endgroup\$ – Scott Seidman Oct 2 '15 at 17:08
1
\$\begingroup\$

The input capacitance combined with the high impedance of the CH3 input could be causing the op amp to oscillate. Try putting a resistor of at least 100 ohms between CH3 and the op amp, after the op amp feedback. The high input impedance of the ADC should prevent that resistor from having a significant effect on the voltage.

This is a common problem with op amps running a capacitive high impedance load.

\$\endgroup\$
  • \$\begingroup\$ The MCP3002 datasheet recommended adding that specific opamp (MCP601) as buffer (see electronics.stackexchange.com/a/193066/54580). So I think it's unlikely it would be that problematic in this application. Or at least they would have mentioned extra precautions to take; it's a pretty long and verbose/hand-holding datasheet. \$\endgroup\$ – Fizz Oct 3 '15 at 3:12
  • \$\begingroup\$ To elaborate on what I said: when driving a capacitive load, the (open-loop) output impedance of the opamp matters. And the manufacturer knows that characteristic, even if they don't put it in the datasheet. See electronics.stackexchange.com/questions/146531/… for more. But what you said here is generally sound advice, even though probably overly cautious in this case. \$\endgroup\$ – Fizz Oct 3 '15 at 3:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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