3

I am attempting to make a temperature monitor based on these links:
1. https://bitbucket.org/pschow/rpiadctherm/src/dbfe8101eeb4/basiclogmcp.py?at=master
2. https://www.paulschow.com/2013/08/monitoring-temperatures-using-raspberry.html

Using a MCP3008 and a thermistor. I have enabled the SPI interface, installed spidev, and I have rewired my circuit several times using different wires. I have also used a voltmeter to test connections and I am getting voltage across my voltage divider. I have a wire connected between the thermistor and resistor to Channel 0 on the MCP3008. I get this error when I run my code:

%Run Thermistor.py
Traceback (most recent call last):
  File "/home/pi/Desktop/Thermistor.py", line 54, in <module>
    print(temp_get(0))
  File "/home/pi/Desktop/Thermistor.py", line 23, in temp_get
    ohms = ((1.0/volts)*3300.0)-10000.0 #calculate the ohms of the thermististor
ZeroDivisionError: float division by zero

I want to see if I am even getting any output from the MCP3008 (like you can on arduino). My code is the following:

import spidev
import math
import time

spi = spidev.SpiDev()
spi.open(0, 0)
# Function to read SPI data from MCP3008 chip
# Channel must be an integer 0-7
def readadc(adcnum):
# read SPI data from MCP3208 chip, 8 possible adc's (0 thru 7)
    if adcnum > 7 or adcnum < 0:
        return -1
    r = spi.xfer2([1, 8 + adcnum << 4, 0])
    adcout = ((r[1] & 3) << 8) + r[2]
    return adcout

def temp_get(adc):

    value = readadc(adc) #read the adc

    volts = (value * 3.3) / 1024.0 #calculate the voltage

    ohms = ((1.0/volts)*3300.0)-10000.0 #calculate the ohms of the thermististor

    lnohm = math.log1p(ohms) #take ln(ohms)

    #a, b, & c values from http://www.thermistor.com/calculators.php

    #using curve Z/D (-4.4%/C @ 25C) Mil Ratio B

    a =  0.001124753301019

    b =  0.000234813406978

    c =  0.000000085355035

    #Steinhart Hart Equation

    # T = 1/(a + b[ln(ohm)] + c[ln(ohm)]^3)

    t1 = (b*lnohm) # b[ln(ohm)]
    c2 = c*lnohm # c[ln(ohm)]
    t2 = math.pow(c2,3) # c[ln(ohm)]^3
    temp = 1/(a + t1 + t2) #calcualte temperature
    tempc = temp - 273.15 - 4 #K to C
    # the -4 is error correction for bad python math
    #print out info

    print ("%4d/1023 => %5.3f V => %4.1f Ω => %4.1f °K => %4.1f °C from adc %d" % (value, volts, ohms, temp, tempc, adc))

    return tempc

while True:
    print(temp_get(0))
    time.sleep(1)
tlfong01
  • 4,665
  • 3
  • 10
  • 24
  • 2
    It is far from clear what this convoluted code is supposed to do, but it seems to assume that voltage and resistance are inversely related which is the ultimate cause of the divide by zero error – Milliways Jan 26 '20 at 21:37
  • I skimmed Pauschow's tutorial and code and found them very good. Once catch is that he is using MCP3208 and so the code will NOT work for your MCP3008. Luckily 10-bit MCP3008 and 12-bit 3208 hardware are almost identical except the analog to digital conversion part, and the SPI command code is also almost the "same". If you indeed are using MCP3008, I can try to find the get around details for you to do a "slight" modification to your MCP3208 code to make it work for MCP3008. – tlfong01 Jan 27 '20 at 01:19
  • Your error message "divide by zero" seems to be caused by Rpi getting zero output from the MCP3008. You might like to read the CHAT record of this Q&A for more details: https://raspberrypi.stackexchange.com/questions/106728/mcp3008-outputting-just-0. – tlfong01 Jan 27 '20 at 01:30
  • In case you found the chat record of the above Q&A messy, here is a clean version: https://penzu.com/p/dfa36278. Happy reading and learning. Cheers. – tlfong01 Jan 27 '20 at 01:56
  • There are other possible causes of trouble: (1) I did not go into the details of pschow's tutorial and check out if he is using "single ended" or "differential" mode of channel input. If you wired the wrong input mode, you might get unexpected results. See Comments #4, 5 of this Q&A for more details: https://raspberrypi.stackexchange.com/questions/107340/analog-ph-meter-ph-4502c-unbootable-pi-3. – tlfong01 Jan 27 '20 at 02:09
  • There are a couple of more causes that you read zero output from MCP3008. (1) You might like to read the chat record of the following Q&A for more details: https://raspberrypi.stackexchange.com/questions/106761/interpreting-voltage-output-on-adc-with-rated-ac-current-sensor. Very briefly, if your analog value is near the boundary/extreme fo the range you wish to measure, and your measurement resolution is very low, say 10 bit, to measure less than 1% of the range, ... – tlfong01 Jan 27 '20 at 03:18
  • MCP3008 does not have enough bits to express a value near zero, so what it can do at best is give you a zero, which is of course misleading, because it can only express that it is near zero. What makes the matter worse is that you are playing with a thermistor, which is logarithmic, which means it is easy to go to either extremes. Perhaps more about logarithmic stuff later. – tlfong01 Jan 27 '20 at 03:22
  • The MCP3008 incorrectly rounding might be it. I used piscope and I have no readings from any of the GPIO pins so I think my wiring might be bad. – raspinooblet Jan 27 '20 at 03:32
  • Ah yes, so the first thing to do troubleshooting is to do the SPI loopback test, to make sure the hardware and software setup is OK. By the way, earlier I mentioned that log scale sensors tend to drift to either extremes causing misleading reading 0 or full sacle. My answer to the following question tries to explain why such sensor reading are unstable or always zero: https://raspberrypi.stackexchange.com/questions/103510/mcp3008-with-photoresistor-analog-to-digital-noisy-readings. – tlfong01 Jan 27 '20 at 07:11
  • By the way, you program has embedded something called "#Steinhart Hart Equation", and mentions that " ... -4 is error correction for bad python math". I lost confidence in this type of code and comments. I have been playing with a couple of ADC and sensors, and I used to have a fully debugged "Convert 2'C compliment 1/2/3 bytes (8/16/24 bit) binary string to signed decimal, in the form of a function, so I have confidence that if input to that function in OK, output must be OK, never mysteriously output 0. You can google such 2'Compliment to signed decimal functions. Cheers. – tlfong01 Jan 27 '20 at 07:21
  • You may find SPI loopback programs in some of my answers related to SPI troubleshooting. However they are mostly Rpi3B+ stretch. You may like to try my new SPI loopback program which (1) can do 5 SPI buses (00, 01, 10, 11, 12). Also there is the Two's Compliment to Signed Decimal function for your try for 10, 16, 24 bit 2'C binary strings. My new SPI loopback program: https://penzu.com/p/926a24f6 – tlfong01 Jan 27 '20 at 07:28
  • And if after keeping trying more troubleshooting tricks but still get stuck, you might like to (1) following another MCP3008 tutorial, (2) forget the hard to play with thermistor and try a more newbie friendly temperature sensor DHT11: (1) Rpi Analog Sensor + MCP3008 - Sushant Narang http://invent.module143.com/daskal_tutorial/raspberry-pi-3-gpio-analog-sensor-mcp3008-mcp3004/

    (2) Rpi DHT11 Temperature + Humidity Sensor - Sushant Narang http://invent.module143.com/daskal_tutorial/raspberry-pi-3-gpio-dht11-digital-temperature-humidity-sensor/. Good luck and cheers.

    – tlfong01 Jan 27 '20 at 07:39
  • Thank you for the help I appreciate it. I'll try your program. – raspinooblet Jan 27 '20 at 14:40

2 Answers2

3

For testing if you drop the bit rate to 100 kbps or so there are a number of methods.

You could use my piscope to see the data being passed between the ADC and the Pi.

An alternative is to use a script to monitor the SPI protocol.

Or just watch the GPIO change state with monitor GPIO.

joan
  • 71,024
  • 5
  • 73
  • 106
  • I used piscope and I have flat lines (no readings) for all my GPIO pins. Perhaps I have bad wiring (the only reason I doubt that is I have rewired the circuit many times and tested voltages across my voltage divider). – raspinooblet Jan 27 '20 at 03:31
  • @raspinooblet I suggest you disconnect everything from the extension header and run gpiotest – joan Jan 27 '20 at 09:14
1

First, your equation to get resistance from voltage is probably wrong. Voltage goes on top. The general equation is "E=IR" or "Voltage = Current * Resistance".

Second, your voltage should almost certainly NOT be zero. Investigate that.

David G.
  • 225
  • 1
  • 2
  • 6
  • The resistance equation comes from the equation to get Vo from a voltage divider. – raspinooblet Jan 27 '20 at 03:18
  • OK.... having derived that equation: I think you've got your constants wrong, and you should factor out the 3.3 volts (while ensuring you don't just do integer division). And the value->volts equation should use 1023, not 1024. – David G. Jan 27 '20 at 04:37
  • Why is that? 2^10 is 1024 – raspinooblet Jan 27 '20 at 15:10
  • True, but the values range from 0 (0 volts) to 1023 (the reference voltage (3.3 volts)). (Actually, you might want to try feeding the ground and reference voltages (at different times) as the input and see what you get. It is possible that feeding in the reference voltage will get you a lower value.) – David G. Jan 27 '20 at 15:24