We work from home most days and use wood as our primary source of heat. To help watch the stove while we're home and gain more insight on how the stove is operating I installed a Pi based temperature monitor. I had an old Pi1 laying around and some K type thermocouples so I turned it all into a monitoring server/DAQ. The combination of flue gas temperature and stove top temperature gives a great indication as to when someone needs to go downstairs and toss some more wood on to maintain the heat/efficiency. Its very convenient knowing how the stove did the night before or how its currently burning.

You can view it live during the winter season here.

You can also view the temperatures of the stove along with air quality measurements here.

Features
  • Stove body and flue gas temperature measurements
  • Flue gas over temperature warning buzzer
  • Air quality monitor for 0.3, 0.5 and 1.0µm - μg/m³
  • Ambient air and humidity sensor
  • Data logging for all measurements, both locally and pushed to InfluxDB
  • Web server to display the graphs (links above)
  • Runs off Power over Ethernet

smoky

Code

import io
import time
import datetime
import board
import busio
import digitalio
import adafruit_max31855
import microcontroller
from multiprocessing import Process

spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
#Do not use hardware CS pins, it won't allow the pythoncircuit library change the CS. Use generic GPIOs and it works fine

cs1 = digitalio.DigitalInOut(board.D23)
cs2 = digitalio.DigitalInOut(board.D24)
max31855_flue = adafruit_max31855.MAX31855(spi, cs1)
max31855_top = adafruit_max31855.MAX31855(spi, cs2)

relay1 = digitalio.DigitalInOut(board.D18)
relay1.direction = digitalio.Direction.OUTPUT

#Setup the buzzer sub-process. When the flue temp is too high sound the buzzer in a loop until temp is corrected.
def buzz_buzz():
    #three short chirps
    relay1.value = True
    time.sleep(0.1)
    relay1.value = False
    time.sleep(0.1)
    relay1.value = True
    time.sleep(0.1)
    relay1.value = False
    time.sleep(0.1)
    relay1.value = True
    time.sleep(0.1)
    relay1.value = False
    #this will run every X seconds, whatever the main loops polling rate is. 

print("Logging temperature to log file")

#beep to announce the start of the script
relay1.value = True
time.sleep(0.1)
relay1.value = False
time.sleep(0.5)

while True:
    try:
        with open("/home/pi/temp_logs/log.csv", "a") as sdc:
            time_stamp = datetime.datetime.now()
            time_stamp = time_stamp.strftime("%Y/%m/%d %H:%M:%S")

            flue_temp = max31855_flue.temperature
            time.sleep(0.050)
            top_temp = max31855_top.temperature

            cpu_temp = open("/sys/class/thermal/thermal_zone0/temp", "r")
            cpu_temp = cpu_temp.readline ()
            cpu_temp = cpu_temp[:-4]

            print("Flue",flue_temp)
            print("Stove Top",top_temp)

            #if the stove is over 50C, record the data to the CSV otherwise drop it
            if flue_temp > 50 or top_temp > 50:
                 sdc.write("{},{},{},{}\n".format(time_stamp, flue_temp, top_temp, cpu_temp))

            # **** BUZZ BUZZ LOOP ****
            #if the flue temp is GREATER than 350C, buzz buzz. The 'Process' call runs the buzz loop in parallel so it doesn't mess with the main loop
            if (flue_temp > 350):
                 #start the buzz routine
                 Process(target=buzz_buzz).start()
                 print("Too hot! Buzzer ahoy! Flue is",flue_temp)

            #sleep before going to the next loop
            time.sleep(10)

    except OSError:
        pass
    except RuntimeError:
        pass