Thursday, September 12, 2013

Basic Light and Temperature Sensing

Here I use two cheap analog sensors for temperature and light:
http://www.adafruit.com/products/165
http://www.adafruit.com/products/161

And convert their analog values to digital values using an Analog to Digital convertor (ADC)
http://www.adafruit.com/products/856

To make things easy I wire these up on an external breadboard connected to the Pi using a Pi cobbler:
http://www.adafruit.com/products/914

Tutorials for installing and using these components can be found on Adafruit's website and I used them heavily. I could explain the technical details of all these components but Adafruit probably does a more elegant job and has tons of documentation so please follow the links for more information. Also the temperature sensor and the ADC are used by TONS of people so a quick google search will give lots of results as well!


import time
import os
import RPi.GPIO as GPIO
# sets up GPIO pins
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
DEBUG = 0
# 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 /= 2 # 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)
# temperature sensor connected channel 0 of mcp3008
adcnum = 0
adclight = 1
#while True:
# read the analog pin (temperature sensor LM35)
read_adc0 = readadc(adcnum, SPICLK, SPIMOSI, SPIMISO, SPICS)
#convert TMP36 #1 digital reading to Celsius temperature
c_temp0 = (((read_adc0 * ( 3300.0 / 1024.0)) - 100.0) / 10.0) - 40.0
c_temp0 = "%.1f" % c_temp0
read_adc1 = readadc(adclight, SPICLK, SPIMOSI, SPIMISO, SPICS)
print 'Temp:', c_temp0, 'C'
print 'Light level:', read_adc1
print
print 'ADC values:' # prints raw values
print 'Pin 1:', read_adc0
print 'Pin 2:', read_adc1
if read_adc1 in range(0, 100):
print "Time to turn on the lights!" # dark
if read_adc1 in range(101, 250):
print "Running our of light, might have to turn on the lights soon..." # indoor room light levels, not very bright
if read_adc1 in range(251, 500):
print "Plenty of light :)" # fairly bright, good growing levels
if read_adc1 in range(501, 1023):
print "Woah, where is the sunblock?" # Tons of light, yay!
view raw airandlight.py hosted with ❤ by GitHub

Also a quick note about the light sensor:
I use a 1K resistor to change by values a bit. This resistor gives me a nice range when the light is bright. If you use a larger resistor (say 10k) it will be better at resolving lower light level differences. Play around with it and use a resistor that gives you a nice dynamic range for the light levels you are interested in sensing.

2 comments:

  1. Could you make a video on how to wire the raspberry pi to the breadboard and the MCP3008

    ReplyDelete
  2. I use the pi cobbler to connect my pi to the breadboard then I followed these instructions explicitly when setting up my sensors. Adafruit has much nicer diagrams and cleaner breadboards then I will ever be able to make.

    https://learn.adafruit.com/reading-a-analog-in-and-controlling-audio-volume-with-the-raspberry-pi/overview

    ReplyDelete