WIFI духовка
- Войдите на сайт для отправки комментариев
Вс, 24/05/2015 - 12:00
Я, как обладатель самой заурядной газовой духовки Гефест (даже градусника нету), озаботился ее модернизацией. Получилась коробочка с Arduino, которая имеет дисплей чтобы видеть время и температуру готовки и кнопки чтобы управлять.
Возможности:
- измеряем температуру в духовке и выводим на дисплей,
- можем задать таймер, который просигналит нам об окончании процесса готовки,
- можем на сайте cook.ber.by выбрать понравившийся нам рецепт, чтобы затем наша коробочка по WIFI могла получить время и температуру готовки.
Материалы:
Arduino NANO, WIFI ESP8266-01, пищалка от мат платы PC, дисплей с кнопками TM1638 (китайский упрощённый), термопара 0-800гр + max6675.

Скетч:
#include <TM1638.h> //Экран #include <MAX6675.h> //градусник #define SID "_Ваш WIFI_" #define PASS "_Ваш пароль_" #define DST_IP "cook.ber.by" #define USER_ID "_Идентификатор который вы получите при регистрации на сайте_" #define CONNECT_ATTEMPTS 5 //количество попыток подключения к WIFI #define RST 3 #define CHP 2 #define LED 13 #define PEZO 5 //пищалка int TCS = 10; // CS pin on MAX6675 int SO = 12; // SO pin of MAX6675 int TSCK = 6; // SCK pin of MAX6675 int units = 1; // Units to readout temp (0 = ˚F, 1 = ˚C) float error = 0.0; // Temperature compensation error int temperature = 0; // Temperature output variable String mess = ""; MAX6675 temp0(TCS,SO,TSCK,units,error); // define a module on data pin 8, clock pin 9 and strobe pin 7 TM1638 module(8, 9, 7); unsigned int temp = 0; unsigned int timer = 0; unsigned long startTime; //время начала unsigned long loopTime =0; //время прошло unsigned long LimitTime = 0; //таймер int ledin = 0; //флаг лампочки //часы минуту секунды и какой-то Х unsigned int h = 0; unsigned int m = 0; unsigned int s = 0; unsigned int x; boolean running = false; //Флаг Запуска отсчета //инициализация сброса void(* resetFunc) (void) = 0; void piezo(){ analogWrite(PEZO, 50); // значение должно находится между 0 и 255 // поэкспериментируйте для получения хорошего тона delay(200); // пауза delayms мс analogWrite(PEZO, 0); // 0 - выключаем пьезо delay(200); // пауза delayms мс } void setup() { pinMode(RST, OUTPUT); pinMode(LED, OUTPUT); pinMode(CHP, OUTPUT); reset(); Serial.begin(9600);//esp8266 startTime = millis(); module.setupDisplay(true, 1); module.clearDisplay(); //приветствие на 3 сек module.setDisplayToString("HELLO"); delay(5000); //выводим нули module.setDisplayToString("00-00-00"); } void temper(){ temperature = temp0.read_temp(5); // Read the temp 5 times and return the average value to the var if(temperature == -1) { // If there is an error with the TC, temperature will be -1 temperature = 0; } } void reset() { digitalWrite(LED, HIGH); digitalWrite(CHP, HIGH); digitalWrite(RST, LOW); delay(100); digitalWrite(RST, HIGH); delay(1000); digitalWrite(LED, LOW); } void loop() { if (running == true) { //таймер запущен startTime = millis(); while (loopTime < LimitTime) { // сравниваем время прошло с вр окончания module.setLEDs(0x0000); // тушим свет s = (LimitTime - loopTime) / 1000; timing(); show(); if (module.getButtons() == 0b00000001) { //кнопка прервать LimitTime = 0; module.setLEDs(0xFFFF); //зажигаем свет module.clearDisplay(); module.setDisplayToString("ABOPT"); //пишем прервано delay (3000); module.setDisplayToString("00-00-00"); module.setLEDs(0x0000); h = 0; m = 0; s = 0; } // моргаем лампочками поочередно для визуализации процесса ledin++; if (ledin == 8) { module.clearDisplay(); mess = String(temp); mess = "TAR " + mess; module.setDisplayToString(mess); //module.setDisplayToDecNumber(temp, 0, false); temper(); delay(2000); mess = String(temperature); mess = "CUR " + mess; module.clearDisplay(); int temp1 = int(temperature); module.setDisplayToString(mess); delay(2000); ledin = 0; } module.setLEDs(0x0000); module.setLED(TM1638_COLOR_GREEN + TM1638_COLOR_RED, ledin); delay(500); loopTime = millis() - startTime; //вычисляем сколько времени прошло } //окончание работы таймера running = false; module.clearDisplay(); module.setDisplayToString("BOOH"); int i = 0; while (i < 10) {++i; piezo();} module.setLEDs(0xFFFF); //delay (10000); resetFunc(); //сбрасываем для ввода нового значения таймера } else { module.setLEDs(0xFFFF); byte btn = module.getButtons(); //опрашиваем кнопки switch (btn) { case 1: h++; // крайняя левая добавить часов if (h > 23) { h = 0; } delay(300); show(); break; case 2: h--; //2 - убавить часов if (h < 0) { h = 23; } delay(300); show(); break; case 4: m++; //3-я добавить минут if (m > 59 ) { m = 0; } delay(300); show(); break; case 8: m--; //4-я...догадайся if (m < 0 ) { m = 59; } delay(300); show(); break; case 16: temp = 200; s = 0; LimitTime = (h * 60 + m) * 60000; module.setDisplayToString("SET TEM"); delay(1000); set_temp(); break; case 64: // 7-я запрсос параметров к сайту module.clearDisplay(); module.setDisplayToString("CONECT"); do { send_get(); } while (timer = 0); delay(300); running = true; break; } } } void set_temp() { module.clearDisplay(); while (running == false) { module.setDisplayToDecNumber(temp, 0, false); byte btn1 = module.getButtons(); //опрашиваем кнопки switch (btn1) { case 1: temp += 10; // крайняя левая добавить температуру if (temp > 400) temp = 400; delay(300); module.clearDisplay(); module.setDisplayToDecNumber(temp, 0, false); break; case 2: temp -= 10; if (temp < 100) temp = 100; delay(300); module.clearDisplay(); module.setDisplayToDecNumber(temp, 0, false); break; case 4: // возврат module.clearDisplay(); module.setDisplayToString("GO 123"); delay(300); running = true; break; } } }//end void temp void send_get() { Serial.println("AT+RST"); delay(1000); if (Serial.find("ready")) ; else { reset(); } delay(500); boolean connected = false; for (int i = 0; i < CONNECT_ATTEMPTS; i++) { module.clearDisplay(); module.setDisplayToDecNumber(i, 0, false); if (connectWiFi()) { delay(3000); module.clearDisplay(); module.setDisplayToString("CONN OK"); delay(1000); connected = true; break; } } if (!connected) { module.clearDisplay(); module.setDisplayToString("NO CONN"); //while (1) chk_serial_io(); reset(); } delay(1000); Serial.println("AT+CIFSR"); //while (Serial1.available()) Serial.write(Serial1.read()); delay(100); Serial.println("AT+CIPMUX=0"); delay(100); String cmd = "AT+CIPSTART=\"TCP\",\""; cmd += DST_IP; cmd += "\",80"; Serial.println(cmd); delay(100); if (Serial.find("Error")) { module.setDisplayToString("NO SITE"); return; } cmd = "GET http://"; cmd += DST_IP; cmd +="/output.php?user="; cmd += USER_ID; cmd +=" HTTP/1.0\r\n\r\n"; Serial.print("AT+CIPSEND="); delay(100); Serial.println(cmd.length()); delay(1000); if (Serial.find(">")) { delay(1000); Serial.println(cmd); } else { Serial.println("AT+CIPCLOSE"); delay(1000); // return; } while (!Serial.find("key{")) {} module.setDisplayToString("KEI OK"); unsigned int i = 0; while (i < 5000) { if (Serial.available()) { temp = Serial.parseInt(); timer = Serial.parseInt(); if (Serial.read() == '}') break; } i++; } LimitTime = long(timer) * 60000; // Serial1.println(LimitTime); delay(1000); } boolean connectWiFi() { Serial.println("AT+CWMODE=1"); String cmd = "AT+CWJAP=\""; cmd += SID; cmd += "\",\""; cmd += PASS; cmd += "\""; Serial.println(cmd); delay(2000); if (Serial.find("OK")) { return true; } else { return false; } } void show() { x = h / 10; module.setDisplayDigit(x, 0, 0); x = h - x * 10; module.setDisplayDigit(x, 1, 0); x = m / 10; module.setDisplayDigit(x, 3, 0); x = m - x * 10; module.setDisplayDigit(x, 4, 0); x = s / 10; module.setDisplayDigit(x, 6, 0); x = s - x * 10; module.setDisplayDigit(x, 7, 0); module.setDisplayToString("-", false, 2); module.setDisplayToString("-", false, 5); } //переводим секунды в часы минуты секунды void timing() { h = s / 3600; s = s - h * 3600; m = s / 60; s = s - m * 60; }1. При запуске приветствие и на экране отображаются нули.
2. Можем выбрать 1-2 (часы +,-) 3-4 (минуты +,-) кнопками время готовки. Кнопка 5 переход к выбору температуры см п.3. Кнопка 7 - запрос режима готовки на сайт cook.ber.by см. п.4.
3. Целевая температура регулируется от 100 до 400-т гр с шагом 10гр. Кнопка 3 - запуск процесса.
4. Если в п.2 выбран запрос на сайт, МК подключается к вашему WIFI и сделает запрос на сайт (На сайте Вы должны заранее ознакомится с рецептом и "выбрать" его). Получив данные по WIFI запускается процесс.
5. В процессе готовки на дисплее поочередно отображается оставшееся время, целевая температура и текущая температура.
6. По окончании процесса МК просигналит звуком.
Питание 3.3V NANO недостаточно для esp8266. Leonardo работало.
Духовку прогрейте заранее минут 5-7, если нет градусника, на 4-5 делении, Вы должны услышать, что газ автоматически убавился.
Я никаких дыр не сверлил и не вмешивался в газовые магистрали своей духовки. Градусник заводил снизу. Если вас посетит гениальная идея регулировать температуру с помощью МК, подумайте 100 раз. Пострадать ПОГИБНУТЬ! можете не только ВЫ, но и Ваши соседи. К тому же наблюдения показали, что встроенная система регулировки имеет свой собственный алгоритм, и "мотор на ручку" мало что изменит.
прикольно. а фото?
На "соплях":
сопли тоже вариант. когда ничего нет это неприкольно
Совет дам тебе умный. Очень. Предусмотри ещё один датчик температуры, и сделай дополнительный режим "Готовка до заданной температуры с поддержанием заданной температуры заданное время". Температурные режимы от 50 до 100 градусов, время поддержания заданной температуры от 0 (выключение по достижению) до 24 часов (низкотемпературная готовка). Датчик должен помещаться непосредственно во внутрь приготавлиемого продукта, и иметь соответственно термостойкий провод, можно использовать термопару от мультиметра, или приобрести что-то оригинальное от духовок имеющих такую функцию.
Когда ты впервые попробуешь свинину запечённую в фольге до температуры 92 градуса, поймёшь что раньше ты не готовил.
А в чем совет-то умный? И уж тем более очень? Сам себя не похвалишь 3 дня как оплеванный?
Когда знаешь что и как готовить, то никакие предметы никаким продуктам ни в какие отверстия пихать не надо.
А в чем совет-то умный? И уж тем более очень? Сам себя не похвалишь 3 дня как оплеванный?
Когда знаешь что и как готовить, то никакие предметы никаким продуктам ни в какие отверстия пихать не надо.
Товарищ считает что равномерно прогревать еду на всю глубину ( на чем и строится основа французской кухни) не возможно без термопар и прочего :) даже боюсь предположить как они раньше готовили.
Это Вам только кажется что вы знаете что и как готовить. Как-же вы интересно "на глазок" определяете какая температура у вас в например в центре запекаемого куска свинины, да и двух совершенно одинаковых кусков свинины не бывает. А знаете-ли 85 градусов, 92, или 98 по результату разница довольно существенная.
Попробуйте просто воспользоваться обычным мультиметром с термопарой, результат Вас удивит. Обещаю.
Относительно "Как-же они готовили раньше". Просто с мение стабильным качеством конечного продукта.
Да и вообще, для чего-то человеку захотелось сделать такое навороченное управление для своей духовки.
Я считаю что в данной теме обязательно стоит подсказать что стоит сделать ещё.
Это Вам только кажется что вы знаете что и как готовить. Как-же вы интересно "на глазок" определяете какая температура у вас в например в центре запекаемого куска свинины, да и двух совершенно одинаковых кусков свинины не бывает. А знаете-ли 85 градусов, 92, или 98 по результату разница довольно существенная.
Попробуйте просто воспользоваться обычным мультиметром с термопарой, результат Вас удивит. Обещаю.
Относительно "Как-же они готовили раньше". Просто с мение стабильным качеством конечного продукта.
Да и вообще, для чего-то человеку захотелось сделать такое навороченное управление для своей духовки.
Я считаю что в данной теме обязательно стоит подсказать что стоит сделать ещё.
Ну да, подсказываю. Питайте в МакДональдсе, там все пропечено с заданной температурой внутри и снаружи и доведено до единообразия.. Дайте угадаю, вы прапорщик? Ибо всякое безобразие доведенное до единообразия и есть воинский порядок.
Если кому интересно. Пришли экраны и max6675. Засев на день за паяльник и ардуинку я все доделал. Выпилил wi fi. Добавил 6 программ работы. Гистерезис на нагрев тэн. Теперь из любой электродуховки можно сделать духовку с электронным управлением. Есть глюки с TM1638, не корректно отображает некоторые символы. Так же с установкой времени небольшая проблема, иногда когда минуты или часы устанавливаешь в - Вместо 23 или 59 почему то лезет 95. А так все работает, релешки щелкают тэны греют. Буду проводить полевые испытания на праздниках.
#include <TM1638.h> //Экран #include <MAX6675.h> //градусник int pr = 0; int Hysteresis = 15; // гистерезис термостата, может изменяться настройками int vent = 2; // Внутренний Вентилятор int lamp = 3; //Лампа int btan = 4; //Нагреватель за вентелятором (1500вт) int dtan = 5; //Нижний нагреватель (1200вт) int uputan = 11; //U образный Верхний верхний тен (860вт) int upwtan = 13; //W образный верхний тен (1500вт) int power = 14; //Power int exhaust = 15; //Вытяжка int PEZO = 16; //пищалка //#define RST 3 //#define CHP 2 //#define LED 13 int TCS = 10; // CS pin on MAX6675 int SO = 12; // SO pin of MAX6675 int TSCK = 6; // SCK pin of MAX6675 int units = 1; // Units to readout temp (0 = ˚F, 1 = ˚C) float error = 0.0; // Temperature compensation error int temperature = 0; // Temperature output variable String mess = ""; MAX6675 temp0(TCS,SO,TSCK,units); // define a module on data pin 8, clock pin 9 and strobe pin 7 TM1638 module(8, 9, 7); unsigned int temp = 0; unsigned int timer = 0; unsigned long startTime; //время начала unsigned long loopTime =0; //время прошло unsigned long LimitTime = 0; //таймер int ledin = 0; //флаг лампочки //часы минуту секунды и какой-то Х unsigned int h = 0; unsigned int m = 0; unsigned int s = 0; unsigned int x; boolean running = false; //Флаг Запуска отсчета //инициализация сброса void(* resetFunc) (void) = 0; void setup() { // pinMode(RST, OUTPUT); // pinMode(LED, OUTPUT); // pinMode(CHP, OUTPUT); pinMode(vent, OUTPUT); pinMode(lamp, OUTPUT); pinMode(btan, OUTPUT); pinMode(dtan, OUTPUT); pinMode(uputan, OUTPUT); pinMode(upwtan, OUTPUT); pinMode(power, OUTPUT); pinMode(exhaust, OUTPUT); pinMode(PEZO, OUTPUT); // pinMode(CHP, OUTPUT); reset(); Serial.begin(9600);//esp8266 startTime = millis(); module.setupDisplay(true, 1); module.clearDisplay(); //приветствие на 3 сек module.setDisplayToString("HELLO"); delay(1000); //выводим нули module.setDisplayToString("00-00-00"); } void temper(){ temperature = temp0.read_temp(); // Read the temp 5 times and return the average value to the var if(temperature == -1) { // If there is an error with the TC, temperature will be -1 temperature = 0; } } void reset() { // digitalWrite(LED, HIGH); // digitalWrite(CHP, HIGH); // digitalWrite(RST, LOW); // delay(100); // digitalWrite(RST, HIGH); // delay(1000); // digitalWrite(LED, LOW); } void loop() { if (running == true) { //таймер запущен startTime = millis(); while (loopTime < LimitTime) { // сравниваем время прошло с вр окончания module.setLEDs(0x0000); // тушим свет s = (LimitTime - loopTime) / 1000; timing(); show(); temper(); if (pr==0) { pr=1 ; } //if (temperature == 0 || temperature > 299 ){running = false; STOP(); resetFunc();} switch (pr) { case 1: prog1(); break; case 2: prog2(); break; case 3: prog3(); break; case 4: prog4(); break; case 5: prog5(); break; case 6: prog6(); break; } //termost(); if (module.getButtons() == 0b00000001) { //кнопка прервать LimitTime = 0; module.setLEDs(0xFFFF); //зажигаем свет module.clearDisplay(); module.setDisplayToString("ABOPT"); //пишем прервано delay (3000); module.setDisplayToString("00-00-00"); module.setLEDs(0x0000); h = 0; m = 0; s = 0; STOP(); } // моргаем лампочками поочередно для визуализации процесса ledin++; if (ledin == 8) { module.clearDisplay(); mess = String(temp); mess = "SET " + mess; module.setDisplayToString(mess); //module.setDisplayToDecNumber(temp, 0, false); temper(); delay(2000); mess = String(temperature); mess = "CUR " + mess; module.clearDisplay(); int temp1 = int(temperature); module.setDisplayToString(mess); delay(2000); ledin = 0; } module.setLEDs(0x0000); module.setLED(TM1638_COLOR_GREEN + TM1638_COLOR_RED, ledin); delay(500); loopTime = millis() - startTime; //вычисляем сколько времени прошло } //окончание работы таймера running = false; module.clearDisplay(); module.setDisplayToString("BOOH"); digitalWrite(PEZO, HIGH ); module.setLEDs(0xFFFF); delay (3000); STOP(); resetFunc(); //сбрасываем для ввода нового значения таймера } else { module.setLEDs(0xFFFF); byte btn = module.getButtons(); //опрашиваем кнопки switch (btn) { case 1: h++; // крайняя левая добавить часов if (h > 23) { h = 0; } delay(300); show(); break; case 2: h--; //2 - убавить часов if (h < 23 ) { h = 23; } delay(300); show(); break; case 4: m++; //3-я добавить минут if (m > 59 ) { m = 0; } delay(150); show(); break; case 8: m--; //4-я...догадайся if (m < 0 ) { m = 59; } delay(150); show(); break; case 64: temp = 200; s = 0; LimitTime = (h * 60 + m) * 60000; module.setDisplayToString("SET TEM"); delay(1000); set_temp(); break; case 128: // программа духовки module.clearDisplay(); // module.setDisplayToString("PROGRAM"); do { pr += 1; if (pr > 6) pr = 0; delay(300); module.clearDisplay(); module.setDisplayToDecNumber(pr, 0, false); } while (timer = 0); delay(300); // running = true; break; } } } void set_temp() { module.clearDisplay(); while (running == false) { module.setDisplayToDecNumber(temp, 0, false); byte btn1 = module.getButtons(); //опрашиваем кнопки switch (btn1) { case 1: temp += 10; // крайняя левая добавить температуру if (temp > 250) temp = 250; delay(300); module.clearDisplay(); module.setDisplayToDecNumber(temp, 0, false); break; case 2: temp -= 10; if (temp < 70) temp = 70; delay(300); module.clearDisplay(); module.setDisplayToDecNumber(temp, 0, false); break; case 4: // возврат module.clearDisplay(); module.setDisplayToString("GO 123"); delay(300); running = true; break; // case 64: // break; s = 0; LimitTime = (h * 60 + m) * 60000; module.setDisplayToString("SET TEM"); delay(1000); set_temp(); break; } } }//end void temp void show() { x = h / 10; module.setDisplayDigit(x, 0, 0); x = h - x * 10; module.setDisplayDigit(x, 1, 0); x = m / 10; module.setDisplayDigit(x, 3, 0); x = m - x * 10; module.setDisplayDigit(x, 4, 0); x = s / 10; module.setDisplayDigit(x, 6, 0); x = s - x * 10; module.setDisplayDigit(x, 7, 0); module.setDisplayToString("-", false, 2); module.setDisplayToString("-", false, 5); } //переводим секунды в часы минуты секунды void timing() { h = s / 3600; s = s - h * 3600; m = s / 60; s = s - m * 60; } void termost(){ // термостатирование if ( temp > ( temperature - 15 ) ) // гистерезис { digitalWrite(power, HIGH); // выключить } if (temp < temperature + 15) { digitalWrite(power, LOW); } } void prog1() { if ( temp > ( temperature + 15 ) && (temp >(temperature + 10)) ) // гистерезис { digitalWrite(power, HIGH ); digitalWrite(dtan, HIGH); digitalWrite(uputan, HIGH ); digitalWrite(lamp, HIGH ); } if ( temp < ( temperature + 15 ) && (temp <(temperature + 10)) ) { digitalWrite(power, HIGH ); digitalWrite(dtan, LOW ); digitalWrite(uputan, LOW ); digitalWrite(lamp, HIGH ); } } void prog2() { if ( temp > ( temperature + 15 ) && (temp >(temperature + 10)) ) // гистерезис { digitalWrite(power, HIGH ); digitalWrite(dtan, HIGH); digitalWrite(uputan, HIGH ); digitalWrite(vent, HIGH); digitalWrite(lamp, HIGH ); } if ( temp < ( temperature + 15 ) && (temp <(temperature + 10)) ) { digitalWrite(power, HIGH ); digitalWrite(dtan, LOW); digitalWrite(uputan, LOW ); digitalWrite(vent, HIGH); digitalWrite(lamp, HIGH ); } } void prog3() { if ( temp > ( temperature + 8 ) && (temp >(temperature + 5)) ) // гистерезис { digitalWrite(power, HIGH ); digitalWrite(vent, HIGH); digitalWrite(btan, HIGH ); digitalWrite(lamp, HIGH ); } if ( temp < ( temperature + 8 ) && (temp <(temperature + 5)) ) { digitalWrite(power, HIGH ); digitalWrite(vent, HIGH); digitalWrite(btan, LOW ); digitalWrite(lamp, HIGH ); } } void prog4(){ if ( temp > ( temperature + 15 ) && (temp >(temperature + 10)) ) // гистерезис { digitalWrite(power, HIGH ); digitalWrite(upwtan, HIGH ); digitalWrite(lamp, HIGH ); } if ( temp < ( temperature + 15 ) && (temp <(temperature + 10)) ) { digitalWrite(power, HIGH ); digitalWrite(upwtan, LOW ); digitalWrite(lamp, HIGH ); } } void prog5(){ if ( temp > ( temperature + 15 ) && (temp >(temperature + 10)) ) // гистерезис { digitalWrite(power, HIGH ); digitalWrite(dtan, HIGH ); digitalWrite(lamp, HIGH ); } if ( temp < ( temperature + 15 ) && (temp <(temperature + 10)) ) { digitalWrite(power, HIGH ); digitalWrite(dtan, LOW ); digitalWrite(lamp, HIGH ); } } void prog6(){ digitalWrite(power, HIGH ); digitalWrite(vent, HIGH); digitalWrite(exhaust, HIGH); } void STOP() { digitalWrite(power, LOW); digitalWrite(vent, LOW); digitalWrite(exhaust, LOW); digitalWrite(lamp, LOW); digitalWrite(dtan, LOW); digitalWrite(upwtan, LOW); digitalWrite(uputan, LOW); digitalWrite(btan, LOW); } void pause() { digitalWrite(power, LOW); digitalWrite(vent, LOW); digitalWrite(exhaust, LOW); digitalWrite(dtan, LOW); digitalWrite(upwtan, LOW); digitalWrite(uputan, LOW); digitalWrite(btan, LOW);; }