Precisie Temperatuur-gestuurde Houtskool Smoker Kit – Bouw Je Eigen BBQ Meesterwerk
Onderdelen en benodigdheden
| Onderdeel | Aantal |
|---|---|
| Arduino MKR1000 | 1 |
| 5V Brushless Blower | 1 |
| MOSFET IRF520N Driver Module | 1 |
| 100k ohm NTC Thermistoren | 1 |
| Breadboard (generiek) | 1 |
| Breadboard draden (generiek) | 1 |
| 3.7V LiPo Batterij >= 700mAh | 1 |
Apps en online diensten
- Arduino IDE
- Microsoft Visual Studio 2015 (voor Universal Windows App)
Over dit project
De achtergrond
Echte BBQ-liefhebbers weten dat houtskool de beste smaak geeft. Propaan en elektrische smokers hebben betere temperatuurregeling, maar missen die smaak. Houtskool vereist constant monitoren en luchtruimtes aanpassen. Wouldn't it be great om te ontspannen terwijl de smoker zelf de temperatuur houdt?
Het project
Een controller die de temperatuur in de smoker meet en de luchtstroom naar de houtskool regelt om de doeltemperatuur te handhaven. Daarnaast externe monitoring van smoker- en vleestemperatuur via een Universal Windows App op elk Windows 10 apparaat. Gebaseerd op de Arduino MKR1000 met ingebouwde WiFi en LiPo-ondersteuning.
De hardware
Temperatuursensor: 100k NTC thermistor in spanningsdeler op analoge ingang. Gekozen omdat ze veel gebruikt worden in 3D-printers (Prusa hotends), dus goedkoop en verkrijgbaar. Al gesoldeerd op hoge-temperatuur siliconen draad. In dunne roestvrijstalen buis (1/4 inch) voor bescherming.
Spanningsdeler: 10k weerstand als vaste tak. Deze waarde ligt dicht bij de weerstand van de thermistor bij typische rooktemperaturen (225°F ≈ 107°C), wat een goed meetbereik geeft (50°F tot >300°F).
Analoge pinnen: A0 voor smoker-temperatuur (korte meetstaf op het rooster). Overige analoge pinnen kunnen extra thermistoren voor vleesproeven aansturen.
Blower: Kleine blower op de luchtruimte van de smoker. Een roestvrijstalen hondenvoerschotel dekt de opening en isoleert de blower thermisch. Blower wordt bestuurd via N-kanaal MOSFET (IRF520N driver module). Gate op digitale pin van MKR1000.
De opbouw
Eerst op breadboard voor simpliciteit. Thermistor-bruggen: 10k van Vcc (3.3V) naar thermistor, andere kant naar GND, jumper van midden naar analoge pin. Meetstaf: buis afsluiten, thermistor inschuiven, krimpkous over draden.
Blower-kant: draden op MOSFET output (polariteit!), LiPo-batterijpack + JST-stekker op MOSFET power-in. JST in MKR1000 batterij-lader. Drie jumpers: Vcc, GND, control van MOSFET naar MKR. 10.000 mAh batterij voor lange looptijd.
Op breadboard extra: 10k trimmer om spanningen te simuleren (testen), LED met 330Ω op pin 0 als indicator voor blower aan/uit.
De software
Twee delen: Arduino sketch (webserver) en Universal Windows App.
Sketch: Gebaseerd op WiFi-server sketch uit "Programming Arduino Next Steps" (Simon Monk). Vaste IP-adres instellen. Pin 0 output. Lus: check client verbinding, serveer webpagina met temperaturen en invoer voor doeltemperatuur. Leest temperatuur via thermistor-brug (Steinhart-Hart / Beta-equatie). Zet blower aan als temp < doeltemp, uit als temp > doeltemp.
Temperatuurmeting: Van analoge reading → spanning over vaste weerstand → stroom (Ohm) → weerstand thermistor → Beta-equatie: 1/T = 1/T0 + 1/Beta * ln(R/R0). T in Kelvin, omrekenen naar Fahrenheit.
Webpagina: Eenvoudige HTML met tabel met temperaturen, invoerveld voor doeltemperatuur, submit-knop.
Universal Windows App
Laadt periodiek de webpagina, parseert temperaturen, toont ze grafisch, stelt doeltemperatuur in. Code voor zowel sketch als app op GitHub.
Code
Smoker Controller Sketch
// sketch_12_04_server_wifi
#include <SPI.h>
#include <WiFi101.h>
char ssid[] = "BeeBar2";
char pass[] = "9254582716";
WiFiServer server(80);
WiFiClient client;
const int numPins = 10;
int pins[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int pinState[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
char line1[100];
char buffer[100];
IPAddress server_IP(192,168,123,90);
float targetTemperature = 225;
float smokerTemperature = 225;
float v0;
void setup() {
Serial.begin(9600);
while (!Serial) {};
for (int i = 0; i < numPins; i++) pinMode(pins[i], OUTPUT);
analogReadResolution(12);
if (WiFi.begin(ssid, pass)) {
WiFi.config(server_IP);
printWifiStatus();
} else {
Serial.println("Could not connect to network");
}
server.begin();
}
void loop() {
client = server.available();
if (client) {
if (client.connected()) {
Serial.print("Request Received: ");
Serial.println(line1);
readHeader();
if (!pageNameIs("/")) {
Serial.print("Invalid Page Requested: ");
Serial.println(line1);
client.stop();
return;
}
readTargetTempParam();
client.println("HTTP/1.1 200 OK\nContent-Type: text/html\n");
sendBody();
delay(1);
client.stop();
} else {
Serial.println("No Client connected ");
}
}
int reading = analogRead(0);
v0 = (float)reading / 1241.0;
smokerTemperature = ThermisterTemp(v0, 100000, 10000, 3950, 25);
digitalWrite(0, smokerTemperature < targetTemperature);
}
void sendBody() {
client.println("");
sendAnalogReadings();
client.println("\n");
}
void sendAnalogReadings() {
client.println("Temperatures
\n");
Serial.print("Pin(0): V="); Serial.print(v0); Serial.print(" Temperature="); Serial.println(smokerTemperature);
client.print("Smoker ");
client.print(" ");
client.print(smokerTemperature);
client.println(" F ");
for (int i = 1; i < 7; i++) {
int reading = analogRead(i);
if (reading > 0) {
float v = (float)reading / 1241.0;
float T = ThermisterTemp(v, 100000, 10000, 3950, 25);
Serial.print("Pin("); Serial.print(i); Serial.print("): "); Serial.print(reading); Serial.print("V="); Serial.print(v); Serial.print(" Temperature="); Serial.println(T);
client.print("Probe ");
client.print(i);
client.print(" ");
client.print(T);
client.println(" F ");
}
}
client.println("
");
}
void readHeader() {
readRequestLine(line1);
while (readRequestLine(buffer) > 1 && buffer[0] != '\n') {}
}
int readRequestLine(char *line) {
char ch;
int i = 0;
while (ch != '\n' && i < 100 && client.available()) {
if (client.available()) {
ch = client.read();
line[i] = ch;
i++;
}
}
line[i] = '\0';
return i;
}
boolean pageNameIs(char* name) {
int i = 4;
char ch = line1[i];
while (ch != ' ' && ch != '\n' && ch != '?') {
if (name[i - 4] != line1[i]) return false;
i++; ch = line1[i];
}
return true;
}
float readTargetTempParam() {
Serial.println(line1);
int len = strlen(line1);
for (int i = 0; i < len; i++) {
if (line1[i] == 't' && line1[i + 1] == '=') {
float val = 0;
for (int j = i + 2; j < len; j++) {
if (isDigit(line1[j])) {
val *= 10;
val += (int)line1[j] - '0';
} else break;
}
targetTemperature = val;
Serial.println(val);
return val;
}
}
return -1;
}
void printWifiStatus() {
Serial.print("SSID: "); Serial.println(WiFi.SSID());
IPAddress ip = WiFi.localIP();
Serial.print("IP Address: "); Serial.println(ip);
long rssi = WiFi.RSSI();
Serial.print("signal strength (RSSI):"); Serial.print(rssi); Serial.println(" dBm");
}
float ThermisterTemp(float Vtherm, int R0therm, int Rfixed, int Beta, int T0) {
double I = (3.3 - Vtherm) / Rfixed;
double Rtherm = Vtherm / I;
T0 += 273.15;
double T = 1.0 / ( (1.0 / (double)Beta) * log(Rtherm / (double)R0therm) + (1.0 / (double)T0) );
return (float)((9 * (T - 273.15)) / 5) + 32;
}
Complete code (sketch + Universal App): GitHub
Schema's
Fritzing-schema (MKR1000 voorgesteld door Arduino Nano): Smoker.fzz en afbeelding.
Productieproces
- Arduino Digitale Dobbelsteen: Bouw Je Eigen LCD-willekeurige Getalgenerator
- Arduino temperatuur- en vochtigheidslogger met DHT11 en Ethernet Shield
- Een Arduino Iron Man bouwen: onderdelen, sensoren en stapsgewijze handleiding
- Find Me: Slimme Item Locator met Arduino en Bluetooth
- Bouw een Functionele, Arduino-aangedreven 3D-geprinte Robotarm – Stap-voor-Stap Handleiding
- DIY Arduino Luchtbevochtiger Controller met Relais – Veilige Hoogspanningsopstelling
- Contactloze temperatuurgate voor snelle, accurate screening
- NeoPixel Matrix Pong op Arduino Nano: Bouw je eigen neon Pong-spel
- Bouw een Aangepaste Arduino Joystick Stuurwiel voor Gaming
- Bouw een krachtige FM-radio ontvanger met Arduino en TEA5767 module
- Arduino 101: Bouw een teller met DHT11 sensor & LCD display