Pimmy
Posts: 8
Joined: Wed Apr 22, 2015 8:04 am

[SOLVED] MCP3002 returns wrong values

Wed Apr 22, 2015 8:40 am

Hello,

I have very basic test setup with an MCP3002 where I measure the voltage on Channel 0. For some bizarre reason however, the read and calculated values are 0.6V lower than the real voltage (I use a precise multimeter) measured from pin_2 on the MCP3002.

I've tried two different ways for retrieving and calculating the value from the MCP3002 (commented out), and both return the same result. I even added a 5 measurement cycle to work out the average value, but that made no difference. The Python script is this:

Code: Select all

#!/usr/bin/python

import spidev
import string
import time
import os
from time import gmtime, strftime

# Definitions
channel_0        = 0               # ADC Channel 0
channel_1        = 1               # ADC Channel 1
delay            = 5               # Delay between readings
measurements     = 5               # Number of readings for average value


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

# Function to read SPI data from MCP3002 chip
# Channel must be an integer 0|1
def ReadChannel(channel):
  data           = 0
  
  for i in range(0,measurements):
    adc          = spi.xfer2([104,0])
    #adc         = spi.xfer2([1,(2+channel)<<6,0])
    
    data         += int(((adc[0]&3) << 8) + adc[1])
    #data        += ((adc[1]&31) << 6) + (adc[2] >> 2)

    time.sleep(0.2)

  data           = float(data) / measurements
  return data

while True:
  # Read the light sensor data
  level_0 = ReadChannel(channel_0)
  volts_0 = round((level_0 * 3.33) / float(1024), 2)

  # Print out results
  timenow = str(strftime("%Y-%m-%d %H:%M:%S", gmtime()))
  print("{} | {} | {}".format(timenow, level_0, volts_0))

  # Wait before repeating loop
  time.sleep(delay)
The 0.6V offset is peculiar here, although it might be just a coincidence. Does anybody have an idea what is wrong?

Thanks,
Pimmy
Last edited by Pimmy on Thu Apr 23, 2015 1:08 pm, edited 1 time in total.

User avatar
DougieLawson
Posts: 39304
Joined: Sun Jun 16, 2013 11:19 pm
Location: A small cave in deepest darkest Basingstoke, UK
Contact: Website Twitter

Re: MCP3002 returns wrong values

Wed Apr 22, 2015 10:40 am

Do you have the latest version of the spidev library?

Try this:

Code: Select all

#!/usr/bin/python

import spidev
from time import sleep

DEBUG = 0

spi = spidev.SpiDev()
spi.open(0,0)

def get_adc(channel):
        if ((channel > 1) or (channel < 0)):
                return -1

        r = spi.xfer2([1,(2+channel)<<6,0])
        ret = ((r[1]&31) << 6) + (r[2] >> 2)
        return ret

A0o = 0
A1o = 0
while True:
        A0 = get_adc(0)
        if A0 != A0o:
                print "A0:", A0
                A0o = A0
        A1 = get_adc(1)
        if A1 != A1o:
                print "A1:", A1
                A1o = A1
        sleep(0.2)
it prints an integer between 0 & 1023 for A0 or A1 value every time it changes.
Note: Any requirement to use a crystal ball or mind reading will result in me ignoring your question.

Criticising any questions is banned on this forum.

Any DMs sent on Twitter will be answered next month.
All non-medical doctors are on my foes list.

User avatar
joan
Posts: 14960
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: MCP3002 returns wrong values

Wed Apr 22, 2015 10:51 am

I assume you expect to read close to 1023. What reading do you actually get?

How stable is the reference voltage?

Post a detailed photo of your set-up.

Pimmy
Posts: 8
Joined: Wed Apr 22, 2015 8:04 am

Re: MCP3002 returns wrong values

Wed Apr 22, 2015 12:39 pm

Thanks DougieLawson and Joan,

I think I have the latest SPIDEV (3.0) - I've downloaded it last week from (git clone git://github.com/doceme/py-spidev)
I also tried the snipped you gave me and it produces the same values. So I wonder if its something to do with the hardware, which brings me to Joan's questions:

The readings from my and DougieLawson's code are the same: 687, 680, 683, 684, 688, 687, 684, 687, 683, 687,...
Yes, I believe the power supply (if this is what you mean by reference voltage) is stable:
I power the entire circuit including the RPi from a 12V battery. I've ripped off the RPi's 5V linear voltage regulator and I am using a switching 3.3V power supply to power the RPi and the MCP. I have filter capacitors in front of the MCP as well (The MCP pulls power from the GPIO pin 17 (its supposed to be DNC, but in fact its the supply +3.3V).

I have attached the photo of the schematic (sorry for the ugly crop, but there is a restriction on the size and reducing the resolution further was making the pin numbers unreadable)
[attachment=0]vrlaRaspberryPi.JPG[/attachment]

Thanks for all your help.
Attachments
vrlaRaspberryPi.JPG
MCP3002 to RPi
vrlaRaspberryPi.JPG (59.61 KiB) Viewed 3883 times

User avatar
joan
Posts: 14960
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: MCP3002 returns wrong values

Wed Apr 22, 2015 1:01 pm

So your reference voltage is 3V3. To eliminate the MCP3002 as the problem connect 3V3 to CH0 or CH1 and see if you read back 1023 (or pretty close).

Pimmy
Posts: 8
Joined: Wed Apr 22, 2015 8:04 am

Re: MCP3002 returns wrong values

Wed Apr 22, 2015 2:00 pm

Very good idea Joan, thanks - I'll try it as soon as I get home tonight

ghp
Posts: 1518
Joined: Wed Jun 12, 2013 12:41 pm
Location: Stuttgart Germany
Contact: Website

Re: MCP3002 returns wrong values

Wed Apr 22, 2015 5:51 pm

Voltage reference is the supply voltage of the device. So any fluctuation in this voltage is affecting the ad result.
And you have a 303k/100k voltage divider in the input path. So an error of 0.6V is 0.15V on ADC input. If you measure this at 600 'points', this could indicate a voltage error of 0.25V away from the 3.3V supply voltage. Which is 7% accuracy for the 3.3 V regulator. Measure the voltage of vdd of the regulator.
Check SPI frequency, at 2.7V it should be 1.2MHz max. Just to be sure. Possibly lower is needed, see below.
spi.max_speed_hz = 500000

The proposal to have a potentiometer (10kOhm) beween 0 and supply voltage is very good: slowly turn this and check for numbers being continuously.

Another source of trouble is the large input impedance you have with prox 75kOhm (the adc 'sees' the 100k and 303k in parallel). The data sheet says it should be as low as possible. Decrease SPI freq in order to give more time for the input capacitance to charge.

And last not least: provide a schottky diode (reverse) from adc input to 3.3 V supply, just in case the adc is not powered and you feed then excessive voltage into the input.

Regards
Gerhard
Last edited by ghp on Wed Apr 22, 2015 6:12 pm, edited 1 time in total.

User avatar
mikronauts
Posts: 2794
Joined: Sat Jan 05, 2013 7:28 pm
Contact: Website

Re: MCP3002 returns wrong values

Wed Apr 22, 2015 5:57 pm

For more accurate results, use a precision voltage reference, and a voltage divider on the inputs to the ADC.

I made a data acquisition board for my experiments that has eight 0-4.096V inputs (1mV steps), and sixteen 0-8.192V inputs (2mV steps)

See http://www.mikronauts.com/raspberry-pi/ ... and-howto/
http://Mikronauts.com - home of EZasPi, RoboPi, Pi Rtc Dio and Pi Jumper @Mikronauts on Twitter
Advanced Robotics, I/O expansion and prototyping boards for the Raspberry Pi

Pimmy
Posts: 8
Joined: Wed Apr 22, 2015 8:04 am

(SOLVED) MCP3002 returns wrong values

Thu Apr 23, 2015 10:44 am

Thanks Guys for all the help.

I've applied the reference voltage of +3.33V to the input of the MCP and the result was spot on:
2015-04-23 09:50:17 | 1023.0 | 3.33
2015-04-23 09:50:22 | 1023.0 | 3.33

With lower voltage, the error grew, which proves Gerhard's theory that the capacitors dont have the time to charge. The moment I've lowered the frequency, the measurement became accurate in the entire range. So the solution to my problem is either lowering the frequency:

Code: Select all

# Open SPI bus
spi = spidev.SpiDev()
spi.open(0,0)
spi.max_speed_hz = 100000
or reducing the values of the 100K-330K resistors to lower the impedance.

The schottky suggestion is also a very good one.

Thanks once again to all of you for the help - without you I would have never been able to solve it.

All the Best,
Pimmy

Return to “Python”