kopia lustrzana https://github.com/botheredbybees/kilnController
Merge branch 'pr/7'
commit
ac1ec77a18
|
@ -29,6 +29,9 @@ gpio_air = 9 # Switches 0-phase det. solid-state-relay
|
|||
### Inputs
|
||||
gpio_door = 18
|
||||
|
||||
max31855 = 0
|
||||
max6675 = 1
|
||||
|
||||
### MAX31855 K-Type Thermocouple I2C
|
||||
gpio_sensor_cs = 27
|
||||
gpio_sensor_clock = 22
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
#!/usr/bin/python
|
||||
import RPi.GPIO as GPIO
|
||||
import time
|
||||
|
||||
class MAX6675(object):
|
||||
'''Python driver for [MAX6675 Cold-Junction Compensated Thermocouple-to-Digital Converter](http://www.adafruit.com/datasheets/MAX6675.pdf)
|
||||
Requires:
|
||||
- The [GPIO Library](https://code.google.com/p/raspberry-gpio-python/) (Already on most Raspberry Pi OS builds)
|
||||
- A [Raspberry Pi](http://www.raspberrypi.org/)
|
||||
|
||||
'''
|
||||
def __init__(self, cs_pin, clock_pin, data_pin, units = "c", board = GPIO.BCM):
|
||||
'''Initialize Soft (Bitbang) SPI bus
|
||||
|
||||
Parameters:
|
||||
- cs_pin: Chip Select (CS) / Slave Select (SS) pin (Any GPIO)
|
||||
- clock_pin: Clock (SCLK / SCK) pin (Any GPIO)
|
||||
- data_pin: Data input (SO / MOSI) pin (Any GPIO)
|
||||
- units: (optional) unit of measurement to return. ("c" (default) | "k" | "f")
|
||||
- board: (optional) pin numbering method as per RPi.GPIO library (GPIO.BCM (default) | GPIO.BOARD)
|
||||
|
||||
'''
|
||||
self.cs_pin = cs_pin
|
||||
self.clock_pin = clock_pin
|
||||
self.data_pin = data_pin
|
||||
self.units = units
|
||||
self.data = None
|
||||
self.board = board
|
||||
|
||||
# Initialize needed GPIO
|
||||
GPIO.setmode(self.board)
|
||||
GPIO.setup(self.cs_pin, GPIO.OUT)
|
||||
GPIO.setup(self.clock_pin, GPIO.OUT)
|
||||
GPIO.setup(self.data_pin, GPIO.IN)
|
||||
|
||||
# Pull chip select high to make chip inactive
|
||||
GPIO.output(self.cs_pin, GPIO.HIGH)
|
||||
|
||||
def get(self):
|
||||
'''Reads SPI bus and returns current value of thermocouple.'''
|
||||
self.read()
|
||||
self.checkErrors()
|
||||
return getattr(self, "to_" + self.units)(self.data_to_tc_temperature())
|
||||
|
||||
def read(self):
|
||||
'''Reads 16 bits of the SPI bus & stores as an integer in self.data.'''
|
||||
bytesin = 0
|
||||
# Select the chip
|
||||
GPIO.output(self.cs_pin, GPIO.LOW)
|
||||
# Read in 16 bits
|
||||
for i in range(16):
|
||||
GPIO.output(self.clock_pin, GPIO.LOW)
|
||||
time.sleep(0.001)
|
||||
bytesin = bytesin << 1
|
||||
if (GPIO.input(self.data_pin)):
|
||||
bytesin = bytesin | 1
|
||||
GPIO.output(self.clock_pin, GPIO.HIGH)
|
||||
time.sleep(0.001)
|
||||
# Unselect the chip
|
||||
GPIO.output(self.cs_pin, GPIO.HIGH)
|
||||
# Save data
|
||||
self.data = bytesin
|
||||
|
||||
def checkErrors(self, data_16 = None):
|
||||
'''Checks errors on bit D2'''
|
||||
if data_16 is None:
|
||||
data_16 = self.data
|
||||
noConnection = (data_16 & 0x4) != 0 # tc input bit, D2
|
||||
|
||||
if noConnection:
|
||||
raise MAX6675Error("No Connection") # open thermocouple
|
||||
|
||||
def data_to_tc_temperature(self, data_16 = None):
|
||||
'''Takes an integer and returns a thermocouple temperature in celsius.'''
|
||||
if data_16 is None:
|
||||
data_16 = self.data
|
||||
# Remove bits D0-3
|
||||
tc_data = ((data_16 >> 3) & 0xFFF)
|
||||
# 12-bit resolution
|
||||
return (tc_data * 0.25)
|
||||
|
||||
def to_c(self, celsius):
|
||||
'''Celsius passthrough for generic to_* method.'''
|
||||
return celsius
|
||||
|
||||
def to_k(self, celsius):
|
||||
'''Convert celsius to kelvin.'''
|
||||
return celsius + 273.15
|
||||
|
||||
def to_f(self, celsius):
|
||||
'''Convert celsius to fahrenheit.'''
|
||||
return celsius * 9.0/5.0 + 32
|
||||
|
||||
def cleanup(self):
|
||||
'''Selective GPIO cleanup'''
|
||||
GPIO.setup(self.cs_pin, GPIO.IN)
|
||||
GPIO.setup(self.clock_pin, GPIO.IN)
|
||||
|
||||
class MAX6675Error(Exception):
|
||||
def __init__(self, value):
|
||||
self.value = value
|
||||
def __str__(self):
|
||||
return repr(self.value)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
# default example
|
||||
cs_pin = 24
|
||||
clock_pin = 23
|
||||
data_pin = 22
|
||||
units = "c"
|
||||
thermocouple = MAX6675(cs_pin, clock_pin, data_pin, units)
|
||||
running = True
|
||||
while(running):
|
||||
try:
|
||||
try:
|
||||
tc = thermocouple.get()
|
||||
except MAX6675Error as e:
|
||||
tc = "Error: "+ e.value
|
||||
running = False
|
||||
print("tc: {}".format(tc))
|
||||
time.sleep(1)
|
||||
except KeyboardInterrupt:
|
||||
running = False
|
||||
thermocouple.cleanup()
|
20
lib/oven.py
20
lib/oven.py
|
@ -10,7 +10,15 @@ import config
|
|||
log = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
from max31855 import MAX31855, MAX31855Error
|
||||
if (config.max31855 == config.max6675):
|
||||
log.error("choose (only) one converter IC")
|
||||
exit()
|
||||
if config.max31855:
|
||||
from max31855 import MAX31855, MAX31855Error
|
||||
log.info("import MAX31855")
|
||||
if config.max6675:
|
||||
from max6675 import MAX6675, MAX6675Error
|
||||
log.info("import MAX6675")
|
||||
sensor_available = True
|
||||
except ImportError:
|
||||
log.warning("Could not initialize temperature sensor, using dummy values!")
|
||||
|
@ -175,7 +183,15 @@ class TempSensor(threading.Thread):
|
|||
class TempSensorReal(TempSensor):
|
||||
def __init__(self, time_step):
|
||||
TempSensor.__init__(self, time_step)
|
||||
self.thermocouple = MAX31855(config.gpio_sensor_cs,
|
||||
if config.max6675:
|
||||
log.info("init MAX6675")
|
||||
self.thermocouple = MAX6675(config.gpio_sensor_cs,
|
||||
config.gpio_sensor_clock,
|
||||
config.gpio_sensor_data,
|
||||
"c")
|
||||
if config.max31855:
|
||||
log.info("init MAX31855")
|
||||
self.thermocouple = MAX31855(config.gpio_sensor_cs,
|
||||
config.gpio_sensor_clock,
|
||||
config.gpio_sensor_data,
|
||||
"c")
|
||||
|
|
Ładowanie…
Reference in New Issue