#!/usr/bin/env python
# This script will read a set of 10K thermocouples using a MCP3008 ADC on a Raspberry Pi running python
# Adapted from work by others... Adafruit Industries, Paul Chow and 4 or 5 others (URL's provided in comments).
# For my needs, I merged their work with some of mine to make this script that calculates temperature and creates a log file for up to 8 ADC ports.
# https://learn.adafruit.com/raspberry-pi-analog-to-digital-converters/mcp3008
# http://www.paulschow.com/2013/08/monitoring-temperatures-using-raspberry.html [basiclogmcp.py]
# ASCII Art Schematic added from Paul's web site
#
#
# +3.3V ---- 10K THERMISTOR --+-- 10K OHM RESISTOR ---- GROUND
# |
# |
# |
# DIGITAL PIN on MCP3008 (the chip I am using)
#
# Pinout
#
# MCP 3208 Pin Pi GPIO Pin # Pi Pin Name
# ============== =============== =============
# 16 VDD 1 3.3 V
# 15 VREF 1 3.3 V
# 14 AGND 6 GND
# 13 CLK 23 GPIO11 SPI0_SCLK
# 12 DOUT 21 GPIO09 SPI0_MISO
# 11 DIN 19 GPIO10 SPI0_MOSI
# 10 CS 24 GPIO08 CE0
# 9 DGND 6 GND
#
# A simple script to log data from the MCP3208
# Based off mcp3208.py
DEBUG = 0 # set DEBUG = 1 if you want to see values displayed as calculations are made
import os
import math
import string
import time
from time import strftime #dropped this in favor of using the logging library
import logging
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
# uncomment to use weather.com for outside temp
# weather_com_result = pywapi.get_weather_from_weather_com('yourzipcodehere')
# you will also ned to install the libraries from https://code.google.com/archive/p/python-weather-api/
# import pywapi
######################################################################################################
# The library for initializing and IO for the MCP3008 is on Adafruit:
# https://learn.adafruit.com/raspberry-pi-analog-to-digital-converters
# follow the link for the MCP3008 SPI or the other I2C if thats what you have. I am using the MCP3008
######################################################################################################
# Simple example of reading the MCP3008 analog input channels and printing them all out.
# Author: Tony DiCola
# License: Public Domain
# Import SPI library (for hardware SPI) and MCP3008 library.
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
# 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 Cobbler
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)
# Set up logging
# https://stackoverflow.com/questions/15474095/writing-a-log-file-from-python-program
log = "ADC_temps.123017.log"
logging.basicConfig(filename=log,level=logging.DEBUG,format='%(asctime)s %(message)s', datefmt='"%Y-%m-%d %H:%M:%S",')
logging.info('============================================')
logging.info('Info: Logging started')
print(' ' * 23)
print('Reading MCP3008 values, press Ctrl-C to quit...')
print('Logging to: ') #print the name of the log file
print(log)
# debug option to see if I can read all ports on the ADC
if DEBUG == 1:
print ('================================')
adcout=readadc(0, 18, 24, 23, 25)
print(adcout)
adcout=readadc(1, 18, 24, 23, 25)
print(adcout)
adcout=readadc(2, 18, 24, 23, 25)
print(adcout)
adcout=readadc(3, 18, 24, 23, 25)
print(adcout)
adcout=readadc(4, 18, 24, 23, 25)
print(adcout)
adcout=readadc(5, 18, 24, 23, 25)
print(adcout)
adcout=readadc(6, 18, 24, 23, 25)
print(adcout)
adcout=readadc(7, 18, 24, 23, 25)
print(adcout)
print ('================================')
# Print a column header for the screen.
print(' ')
print('| Time | {1:>4} | {2:>4} | {3:>4} | {4:>4} | ' .format(*range(8)))
#print('-' * 60)
#print('/n')
logging.info('Date-Time,OutTemp,Port1,port2,port3,port4')
logging.info('-' * 50)
logging.info(" ")
value=0
volts = 1 # #initial values to prevent division by zero error
ohms = 1 # #initial values to prevent division by zero error
lnohm = 0
temp = 0
tempc = 0
c2 = 0
t1 = 0
t2 = 0
# Added an array to hold the temperature calculations before output
temps = [0]*10
values = [0]*10
# from http://raspberrypi.powersbrewery.com/project-8-temperature-sensing-thermistor/
# Create a function to convert a resistance reading from our
# thermistor to a temperature in Celsius which we convert to
# Fahrenheit and return to our main loop
def temperature_reading(R):
B = 3250 # Thermistor constant from thermistor datasheet
R0 = 10000.0 # Resistance of the thermistor being used
t0 = 273.15 # 0 deg C in K
t25 = t0 + 25.0 # 25 deg C in K
# Steinhart-Hart equation
inv_T = 1/t25 + 1/B * math.log(R/R0)
T = (1/inv_T - t0) * 1
return T * 9.0 / 5.0 + 32.0 # Convert C to F
# Main program loop.
while True:
# Read the ADC channel values and calculate temps, log them
# The read_adc function will get the value of the specified channel (0-7).
#logging.warning('To do: log a warning message if the temperature is over a threshold')
print('-' * 50)
i = 0 #for i in range (0-3):
while i <= 3:
value = readadc(i, 18, 24, 23, 25)
values[i] = value
#calculate the voltage
volts = (value * (3.3 / 1024)) #GG_changed grouping
if value == 0:
# cheating a bit to prevent division by zero later on
value = 880
ohms = ((1024/value-1)*10000) #calculate the ohms of the thermististor
t = temperature_reading(ohms)
#output to log and screen
if DEBUG == 1:
print(value)
print(volts)
print(ohms)
print("Port %i ADC reading is: %5.2f" % (i, value))
print("Port %i temperature is: %5.2f" % (i, t))
logging.info('5.2%f' % t) #write to log
temps[i] = t
i = i+1 #increment port number
if i == 4: # call for print and log
print('%s,%6.2f,%6.2f,%6.2f,%6.2f' % (strftime("%D-%H:%M"), temps[0],temps[1],temps[2],temps[3]))
logging.info('%6.2f,%6.2f,%6.2f,%6.2f' % (temps[0],temps[1],temps[2],temps[3]))#write to log
# logging.info('%5.2f,%5.2f,%5.2f,%5.2f' % (values[0],values[1],values[2],values[3])) #write to log
time.sleep(2) # Pause, then repeat the while true loop over and over again...
i = 0 # keep the while loop going
GPIO.cleanup() #outta here.