Not sure this is of use for anyone, but I thought I post a little project I implemented recently and that's pretty straight forward to implement.
When we were at our friends' place he showed off his cool new wifi-enabled BBQ-thermometer with the corresponding app. Nice gadget, that he got from his wife as a birthday present. When I looked it up online and saw the price tag of well above 150,- EUR I thought there must be a much cheaper way of getting this... And there is: a simple, mysensorized BBQ-node!
Next time they came over to our place we were standing in the kitchen and when it was time to check on the meat, all I did was ask Alexa - the effect was phenomenal
There are many good tutorials on the web on how to connect a thermistor and read the temperature, I've used this as the basis: https://learn.adafruit.com/thermistor/using-a-thermistor
Here's my simple setup:
I'm using a Nano powered with an external 5V supply, two Maverick temperature probes and 2 extra resistors for the voltage dividers. Turns out the two Mavericks are the biggest price items with around 20,- EUR each. There are much cheaper probes available, but I wanted to make sure they are durable and avoid having to re-calibrate the whole thing every time I have to get a new thermistor probe.
Please note, this project is not meant to actively control the smoker temperature! There are many projects to follow online that go down that road. I'm a bit of an old-fashioned BBQ-fan, I feel controlling the smoker temp and adjusting it when needed is part of the fun. So all this does is to read smoker and meat temperature...
Mainly to be able to check the temperature while developing the BBQ-node, I also added a 4-line LCD display (https://www.mysensors.org/build/display). It actually turned out to be quite handy, as it allows to check the temp while in the yard and without a handheld or Alexa.
Wiring everything up is pretty straight forward following the steps in the above two links for thermistor and display. It took me a bit to figure out the right settings for the thermistor as I didn't get data sheets or resistance curves. There's still some improvement potential to get the temperature readings more accurate, but for now precision is good enough.
(note: in ths pic, the smoker room temp probe was not attached, yielding a wrong value in the display!)
// -----------------------
// myBBQ-Node
// -----------------------
// Enable debug prints
#define MY_DEBUG
//#define MY_DEBUG_VERBOSE
#define MY_TRANSPORT_WAIT_READY_MS 1
// define node specific configuration
// ***********************************
// BBQ Thermometer
// ***********************************
#define MY_NODE_ID 13
char MY_BBQ_NODE_VERSION = "0.4";
char MY_BBQ_NODE_DATE = "02.07.2017";
#define HEARTBEAT_INTERVAL 6000 // send heartbeat every 2 min
// which analog pin to connect
#define THERMISTORPIN_A A0
#define THERMISTORPIN_B A1
// temp. for nominal resistance (almost always 25 C)
#define TEMPERATURENOMINAL 25
// resistance at this nominal temperature
#define THERMISTORNOMINAL_A 1000000
#define THERMISTORNOMINAL_B 1000000
// the value of the 'other' resistor
#define SERIESRESISTOR_A 920000
#define SERIESRESISTOR_B 1000000
// how many samples to take and average, more takes longer
// but is more 'smooth'
#define NUMSAMPLES 20
// The beta coefficient of the thermistor (usually 3000-4000)
#define BCOEFFICIENT_A 3950
#define BCOEFFICIENT_B 3950
// Enable and select radio type attached
#define MY_RADIO_NRF24
//#define MY_RF24_CHANNEL 77
//#define MY_RADIO_RFM69
//#define MY_RS485
#include <SPI.h>
// Enabled repeater feature for this node
//#define MY_REPEATER_FEATURE
#include <MySensors.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Initialize display. Google the correct settings for your display.
// The follwoing setting should work for the recommended display in the MySensors "shop".
//LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
LiquidCrystal_I2C lcd(0x27, 20, 4);
// Sleep time between sensor updates (in milliseconds)
// Must be >1000ms for DHT22 and >2000ms for DHT11
//static const uint64_t UPDATE_INTERVAL = 60000;
static const uint64_t UPDATE_INTERVAL = 300000;
#define CHILD_ID_TEMP_SMOKER 0
#define CHILD_ID_TEMP_MEAT 1
bool metric = true;
MyMessage msgTempSmoker(CHILD_ID_TEMP_SMOKER, V_TEMP);
MyMessage msgTempMeat(CHILD_ID_TEMP_MEAT, V_TEMP);
void presentation()
{
// Send the sketch version information to the gateway
sendSketchInfo("BBQ Temp", "0.2");
// Register all sensors to gw (they will be created as child devices)
present(CHILD_ID_TEMP_SMOKER, S_TEMP);
present(CHILD_ID_TEMP_MEAT, S_TEMP);
metric = getControllerConfig().isMetric;
}
void setup() {
float temp_smoker;
float temp_meat;
// connect AREF to 3.3V and use that as VCC, less noisy!
analogReference(EXTERNAL);
temp_meat = analogRead(THERMISTORPIN_A);
temp_smoker = analogRead(THERMISTORPIN_B);
float meat = calc_steinhart(temp_meat, SERIESRESISTOR_A, THERMISTORNOMINAL_A, BCOEFFICIENT_A);
float smoker = calc_steinhart(temp_smoker, SERIESRESISTOR_B, THERMISTORNOMINAL_B, BCOEFFICIENT_B);
// initialize the lcd for 16 chars 2 lines and turn on backlight
//lcd.begin(16,2);
lcd.init();
lcd.clear();
lcd.home();
lcd.setCursor (0,0);
lcd.backlight();
lcd.print("myBBQ Thermometer");
lcd.setCursor (10,2);
lcd.print("Vers. " + MY_BBQ_NODE_VERSION);
lcd.setCursor (10,3);
lcd.print(MY_BBQ_NODE_DATE);
delay(5000);
lcd.clear();
lcd_update(smoker,meat);
}
void loop(void) {
uint8_t i;
float av_smoker;
float av_meat;
// take NUMSAMPLES samples in a row, with a slight delay
av_meat = 0;
av_smoker = 0;
for (i=0; i< NUMSAMPLES; i++) {
av_meat += analogRead(THERMISTORPIN_A);
delay(50);
av_smoker = analogRead(THERMISTORPIN_B);
delay(50);
lcd.setCursor (0+i,1);
lcd.print("_");
}
// average all the samples out
av_meat /= NUMSAMPLES;
av_smoker /= NUMSAMPLES;
Serial.print("Average analog reading 1: ");
Serial.println(av_meat);
Serial.print("Average analog reading 2: ");
Serial.println(av_smoker);
float temp_meat = calc_steinhart(av_meat, SERIESRESISTOR_A, THERMISTORNOMINAL_A, BCOEFFICIENT_A);
float temp_smoker = calc_steinhart(av_smoker, SERIESRESISTOR_B, THERMISTORNOMINAL_B, BCOEFFICIENT_B);
Serial.print("Temp Meat ");
Serial.print(temp_meat);
Serial.println(" *C");
Serial.print("Temp Smoker ");
Serial.print(temp_smoker);
Serial.println(" *C");
lcd_update(temp_smoker,temp_meat);
send(msgTempSmoker.set(temp_smoker, 1));
send(msgTempMeat.set(temp_meat, 1));
delay(1000);
}
float calc_steinhart(float reading, float RSER, float RNOM, float BCOEFF) {
uint8_t i;
// convert the value to resistance
reading = 1023 / reading - 1;
reading = RSER / reading;
Serial.print("RSER ");
Serial.println(RSER);
Serial.print("RNOM ");
Serial.println(RNOM);
Serial.print("BCOEFF ");
Serial.println(BCOEFF);
Serial.print("Thermistor resistance ");
Serial.println(reading);
float steinhart;
steinhart = reading / RNOM; // (R/Ro)
steinhart = log(steinhart); // ln(R/Ro)
steinhart /= BCOEFF; // 1/B * ln(R/Ro)
steinhart += 1.0 / (TEMPERATURENOMINAL + 273.15); // + (1/To)
steinhart = 1.0 / steinhart; // Invert
steinhart -= 273.15; // convert to C
Serial.print("cal_steinhart Temp: ");
Serial.print(steinhart);
Serial.println(" *C");
return steinhart;
}
void lcd_update(float smoker, float meat) {
lcd.clear();
lcd.home();
// print information to lcd display
lcd.setCursor (0,0);
lcd.print("BBQ: ");
lcd.print("Pulled Pork");
lcd.setCursor (0,2);
lcd.print("Smoker:");
lcd.setCursor (0,3);
if (smoker <= 0) {
lcd.print("- n.a. -");
} else if (smoker <= 10) {
lcd.print("- low -");
} else if (smoker > 200) {
lcd.print("+ high +");
} else {
lcd.print(smoker);
lcd.print(" *C");
}
lcd.setCursor (11,2);
lcd.print("Fleisch:");
lcd.setCursor (11,3);
if (meat <= 0) {
lcd.print("- n.a. -");
} else if (meat <= 10) {
lcd.print("- low -");
} else if (meat > 120) {
lcd.print("+ high +");
} else {
lcd.print(meat);
lcd.print(" *C");
}
}