Подключаем электропечь к андроиду с помощью Wemos D1 mini

  • Цена: 2$
  • Давненько я не ковырял эту суперштуку под названием Wemos D1 mini, а тут оказия.

    В общем есть электропечь Indesit:

    Подключаем электропечь к андроиду с помощью Wemos D1 mini

    Печь отличная, но в последнее время у нее стали баловаться регуляторы мощности. На двух конфорках работать стали нестабильно и непредсказуемо, невозможно выставить нужную температуру, то выкипает, то совсем гаснет.

    Регуляторы мощности там стоят вот такие:

    Подключаем электропечь к андроиду с помощью Wemos D1 mini

    Я пробовал конечно их разбирать, чистил контакты, регулировал, но видимо металл уже изменил своих свойства и толку от этого практически не было.

    И тут возникла мысль: «У меня есть Wemos D1 mini, в шаговой доступности есть твердотельные реле, почему нет?»

    Итак беру пару вот таких твердотельных реле SSR-10DA:

    Подключаем электропечь к андроиду с помощью Wemos D1 mini

    Они популярные, есть на каждом углу. Есть несколько моделей, в маркировке нас интересуют цифра 10 (ток в амперах) и буквы DA (наша нагрузка будет работать на переменном напряжении, а управлять ею мы будем постоянным напряжением).

    Напряжения Wemos D1 mini 3.3V вполне хватает, чтобы закрывать и открывать реле.

    Итак, подключаем реле в разрыв питающего конфорку провода (между конфоркой и родным регулятором мощности конфорки). Сделал так на всякий случай, для дополнительной защиты. Т.е. чтобы наш Wemos D1 mini управлял конфоркой, нам нужно вручную ее включить (поставить на макс огонь). На управляющие контакты кидаем провода от пинов Wemos D1 mini (не забываем про полярность), осталось только запилить скетч.

    Пока подпаивал пины, вспомнил, что у меня валяются без дела несколько датчиков, остались от старых проектов. И снова «почему нет?».

    Подключил к Wemos D1 mini датчик атмосферного давления BMP180 (на борту он кстати имеет и датчик температуры), и датчик температуры и влажности DHT-21. Вот такие:

    Подключаем электропечь к андроиду с помощью Wemos D1 mini

    Подключаем электропечь к андроиду с помощью Wemos D1 mini

    Подключение описывать не буду, в интернете море информации. Они очень популярные.

    Пилим скетч:

    Дополнительная информация
    #include <ESP8266WiFi.h>
    
    #include <ESP8266WebServer.h>
    #include <EEPROM.h>
    #include <Adafruit_BMP085.h>
    #include "DHT.h"

    #define D0 16 //TDS
    #define D1 5 //SCL
    #define D2 4 //SDA
    #define D3 0
    #define D4 2 //LED помпа
    #define D5 14 // Земля
    #define D6 12 // 2 реле
    #define D7 13 // 1 реле
    #define D8 15
    #define TX 1
    #define RX 3
    const char* ssid = "Home";
    const char* password = "11111111";
    String response = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
    String response_klimat = "0000000000000000000000000000000000000000000000000000000000000000000000000000000000";
    String delimiter = "|";
    String delimiter_2 = "@";
    String argument = "000000000000000000000000000000000000000";
    String argument_name = "000000000000000000000000000000000000000";
    String a = "0000000000000000000000";
    ESP8266WebServer server(80);
    float PERIOD = 10.0;
    const float MINIMAL_PERIOD = 0.5;
    int power_rate_1 = 0;
    int power_rate_2 = 0;
    float duration_on_1 = 0;
    float duration_on_2 = 0;
    float duration_off_1 = 0;
    float duration_off_2 = 0;
    unsigned long time_on_1;
    unsigned long time_on_last_time_1 = 0;
    unsigned long time_off_last_time_1 = 0;
    unsigned long time_on_2;
    unsigned long time_on_last_time_2 = 0;
    unsigned long time_off_last_time_2 = 0;
    unsigned long timer_1;
    unsigned long timer_2;
    unsigned long timer_start_1;
    unsigned long timer_start_2;
    boolean timer_enable_1 = false;
    boolean timer_enable_2 = false;
    boolean power_on_1 = false;
    boolean power_on_2 = false;
    boolean enable_1 = false;
    boolean enable_2 = false;
    //***********HISTORY************************************
    const int SIZE_HISTORY = 100;
    long HISTORY_PERIOD = 600000;
    unsigned long array_millis[SIZE_HISTORY];
    float history_temp[SIZE_HISTORY];
    float history_temp_dht[SIZE_HISTORY];
    float history_baro[SIZE_HISTORY];
    float history_hum[SIZE_HISTORY];
    unsigned long history_last_time=0;
    int history_counter = 0;
    //******DHT-21*******************************************
    #define DHTPIN 2
    #define DHTTYPE DHT21
    DHT dht(DHTPIN, DHTTYPE);
    float t; //Мгновенная температура
    float h; //Мгновенная влажность
    float average_t; //Средняя температура
    float average_h; //Средняя влажность
    float t_array [10] ; //Массив для температуры
    float h_array [10] ; //Массив для влажности
    int array_counter = 0; //Счетчик переполнения массива
    boolean dht_first_flag = 1;
    unsigned long dht_last_time =0;
    //***********BMP085***************************************
    Adafruit_BMP085 bmp;
    float baro_temperature;
    float baro_pressure;
    float average_bar_pressure; //Среднее давление
    float average_bar_temperature; //Средняя температура
    float bar_temperature_array [10] ; //Массив для температуры
    float bar_pressure_array [10] ; //Массив для давления
    int bar_array_counter = 0; //Счетчик переполнения массива
    boolean bar_first_flag = 1;
    unsigned long bmp_last_time;
    //--------------------EEPROM----------------------------
    #define EE_period 0
    #define EE_freq_1 10
    #define EE_freq_2 2

    //****************************************************************************************

    void handleRoot() {
    Create_info_response();
    server.send(200, "text/html", response_klimat);
    }
    void handleNotFound(){
    String message = "404. Not Foundnn";
    server.send(404, "text/plain", message);
    }
    void handleSet() {
    argument = server.arg(0);
    a = server.arg(0);
    if(server.argName(0) == "info") {
    Create_info_response();
    Serial.println(response_klimat);
    server.send ( 200, "text/plain", response_klimat );
    }
    if(server.argName(0) == "power_1") {
    int old = power_rate_1;
    power_rate_1 = a.toInt();
    if(old == 0 && power_rate_1 > 0)time_on_1 = millis();
    if(power_rate_1 > 0) enable_1 = true;
    else {
    enable_1 = false;
    power_on_1 = false;
    timer_enable_1 = false;
    digitalWrite(D7, LOW);
    }
    Create_info_response();
    server.send ( 200, "text/plain", response_klimat );
    }
    if(server.argName(0) == "power_2") {
    int old = power_rate_2;
    power_rate_2 = a.toInt();
    if(old == 0 && power_rate_2 > 0)time_on_2 = millis();
    if(power_rate_2 > 0) {
    enable_2 = true;
    }
    else {
    enable_2 = false;
    power_on_2 = false;
    timer_enable_2 = false;
    digitalWrite(D6, LOW);
    }
    Create_info_response();
    server.send ( 200, "text/plain", response_klimat );
    }
    if(server.argName(0) == "timer_1") {
    int value = a.toInt();
    if(value > 0) {
    timer_1 = value * 60000L;
    timer_enable_1 = true;
    timer_start_1 = millis();
    }else{
    timer_enable_1 = false;
    }
    Create_info_response();
    server.send ( 200, "text/plain", response_klimat );
    }
    if(server.argName(0) == "timer_2") {
    int value = a.toInt();
    if(value > 0) {
    timer_2 = value * 60000L;
    timer_enable_2 = true;
    timer_start_2 = millis();
    }else{
    timer_enable_2 = false;
    }
    Create_info_response();
    server.send ( 200, "text/plain", response_klimat );
    }
    if(server.argName(0) == "klimat") {
    response_klimat = "";
    response_klimat += average_bar_pressure;
    response_klimat += delimiter;
    response_klimat += average_bar_temperature;
    response_klimat += delimiter;
    response_klimat += average_h;
    response_klimat += delimiter;
    response_klimat += average_t;
    server.send ( 200, "text/plain", response_klimat);
    }
    if(server.argName(0) == "history") {
    Create_history_response();
    server.send ( 200, "text/plain", response);
    }
    if(server.argName(0) == "freq") {
    int value = a.toInt();
    HISTORY_PERIOD = value * 1000L;

    EEPROM.begin(10);
    int first_byte = value/256;
    int second_byte = value%256;
    EEPROM.write(EE_freq_1, first_byte);
    EEPROM.commit();
    EEPROM.write(EE_freq_2, second_byte);
    EEPROM.commit();
    EEPROM.end();

    response_klimat = value;
    server.send ( 200, "text/plain", response_klimat);
    }
    if(server.argName(0) == "period") {
    int value = a.toInt();
    PERIOD = (float)value;
    EEPROM.write(EE_period, (byte)value);
    EEPROM.commit();
    response_klimat = value;
    server.send ( 200, "text/plain", response_klimat);
    }
    /*
    response_klimat = "Get response: ";
    response_klimat += server.argName(0);
    response_klimat += " Value: ";
    response_klimat += a.toInt();
    response_klimat += " time:";
    response_klimat += millis();
    Serial.println(response_klimat);
    */
    }
    //****************************************************************************************
    //****************************************************************************************

    void setup(void){

    pinMode(D6, OUTPUT);
    pinMode(D7, OUTPUT);
    pinMode(D5, OUTPUT);
    digitalWrite(D5, LOW);
    digitalWrite(D6, LOW);
    digitalWrite(D7, LOW);
    Serial.begin(115200);
    Wire.begin();
    dht.begin();
    bmp.begin();

    EEPROM.begin(10);
    PERIOD = (float)EEPROM.read(EE_period);


    int first_byte = EEPROM.read(EE_freq_1);
    int second_byte = EEPROM.read(EE_freq_2);
    HISTORY_PERIOD = (first_byte*256+second_byte) * 1000L;
    EEPROM.end();

    WiFi.begin(ssid, password);

    Serial.println("");
    while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    }
    Serial.println("");
    Serial.print("Connected to ");
    Serial.println(ssid);
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());

    server.on("/", handleRoot);
    server.on("/set", handleSet);
    server.onNotFound(handleNotFound);
    server.begin();
    Serial.println("HTTP server started");


    }
    //**********************LOOP**************************************************************
    //****************************************************************************************

    void loop(void){
    server.handleClient();
    Calc_duration();
    Pechka();
    Baro(1000);
    DHT_21(2000);
    History(HISTORY_PERIOD);
    Timer();

    }
    //****************************************************************************************
    //****************************************************************************************
    void History(long freq){
    if((millis()-history_last_time)>freq){

    history_temp_dht[history_counter] = average_t;
    history_temp[history_counter] = average_bar_temperature;
    history_baro[history_counter] = average_bar_pressure;
    history_hum[history_counter] = average_h;
    array_millis[history_counter] = millis();
    history_counter ++;
    if(history_counter >= SIZE_HISTORY) history_counter = 0;

    history_last_time = millis();
    }
    }
    void Create_history_response(){
    response = "";
    for(int i = 0; i < SIZE_HISTORY; i++){
    response_klimat = "";
    response_klimat += history_baro[i];
    response_klimat += delimiter;
    response_klimat += history_temp[i];
    response_klimat += delimiter;
    response_klimat += history_hum[i];
    response_klimat += delimiter;
    response_klimat += history_temp_dht[i];
    response_klimat += delimiter;
    long m = millis() - array_millis[i];
    response_klimat += m;
    response_klimat += delimiter_2;
    response += response_klimat;
    }

    }
    void Create_info_response(){
    response_klimat = "";
    response_klimat += power_rate_1;
    response_klimat += delimiter;
    response_klimat += power_on_1;
    response_klimat += delimiter;
    if(power_rate_1 > 0) response_klimat += millis() - time_on_1;
    else response_klimat += 0;
    response_klimat += delimiter;
    if(timer_enable_1) response_klimat += timer_start_1 + timer_1 - millis();
    else response_klimat += 0;
    response_klimat += delimiter;

    response_klimat += power_rate_2;
    response_klimat += delimiter;
    response_klimat += power_on_2;
    response_klimat += delimiter;
    if(power_rate_2 > 0) response_klimat += millis() - time_on_2;
    else response_klimat += 0;
    response_klimat += delimiter;
    if(timer_enable_2) response_klimat += timer_start_2 + timer_2 - millis();
    else response_klimat += 0;
    response_klimat += delimiter;
    response_klimat += HISTORY_PERIOD;
    response_klimat += delimiter;
    response_klimat += PERIOD;
    }
    //---------Барометр-----------------------------------------------------
    void Baro(int freq){
    if((millis()-bmp_last_time)>freq){
    baro_pressure = bmp.readPressure()/133.322;
    baro_temperature = bmp.readTemperature();

    if(bar_first_flag){
    for (int m = 0; m < 10; m++){
    bar_temperature_array[m] = baro_temperature;
    bar_pressure_array[m] = baro_pressure;
    bar_first_flag = 0;
    }
    }
    bar_temperature_array[bar_array_counter] = baro_temperature;
    bar_pressure_array[bar_array_counter] = baro_pressure;
    bar_array_counter++;
    if(bar_array_counter>9){bar_array_counter=0;}
    float m1 = 0;
    float m2 = 0;
    for (int m = 0; m < 10; m++){
    m1 = m1 + bar_temperature_array[m];
    m2 = m2 + bar_pressure_array[m];}
    average_bar_pressure = m2/10.00;
    average_bar_temperature = m1/10.00;

    bmp_last_time = millis();
    }
    }
    //---------------DHT--------------------------------------------
    void DHT_21(int freq){
    if ((millis()-dht_last_time)>freq){
    t = dht.readTemperature();
    h = dht.readHumidity();


    if(dht_first_flag){
    for (int m = 0; m < 10; m++){
    t_array[m] = t;
    h_array[m] = h;}
    dht_first_flag = 0;
    }

    t_array[array_counter] = t;
    h_array[array_counter] = h;
    array_counter++;
    if(array_counter>9)array_counter=0;
    float summa_t = 0;
    float summa_h = 0;
    for (int m = 0; m < 10; m++){
    summa_t += t_array[m];
    summa_h += h_array[m];
    }
    average_t = summa_t/10.00;
    average_h = summa_h/10.00;
    dht_last_time = millis();}
    }
    //---------Pechka-------------------------------------------------------
    void Pechka(){
    if(enable_1){
    if(power_on_1){
    if(millis() - time_on_last_time_1 > duration_on_1 * 1000.0){
    power_on_1 = false;
    time_off_last_time_1 = millis();
    digitalWrite(D7, LOW);
    //Serial.println("1 off");
    }
    }
    if(!power_on_1){
    if(millis() - time_off_last_time_1 > duration_off_1* 1000.0){
    power_on_1 = true;
    time_on_last_time_1 = millis();
    digitalWrite(D7, HIGH);
    //Serial.println("1 on");
    }
    }
    }else{
    digitalWrite(D7,0);
    }
    if(enable_2){
    if(power_on_2){
    if(millis() - time_on_last_time_2 > duration_on_2 * 1000.0){
    power_on_2 = false;
    time_off_last_time_2 = millis();
    digitalWrite(D6, LOW);
    //Serial.println("2 off");
    }
    }
    if(!power_on_2){
    if(millis() - time_off_last_time_2 > duration_off_2* 1000.0){
    power_on_2 = true;
    time_on_last_time_2 = millis();
    digitalWrite(D6, HIGH);
    //Serial.println("1 onn");
    }
    }
    }else{
    digitalWrite(D6,0);
    }
    }
    void Calc_duration(){
    if(power_rate_1 == 100){
    duration_on_1 = 600;
    duration_off_1 = 0;
    }
    if(power_rate_1 == 0){
    duration_on_1 = 0;
    duration_off_1 = 100000;
    }
    if(power_rate_1 < 100 && power_rate_1 > 0){
    duration_on_1 = power_rate_1/100.0 * PERIOD;
    duration_off_1 = PERIOD - duration_on_1;
    }
    if(power_rate_2 == 100){
    duration_on_2 = 600;
    duration_off_2 = 0;
    }
    if(power_rate_2 == 0){
    duration_on_2 = 0;
    duration_off_2 = 100000;
    }
    if(power_rate_2 < 100 && power_rate_2 > 0){
    duration_on_2 = power_rate_2/100.0 * PERIOD;
    duration_off_2 = PERIOD - duration_on_2;
    }
    }
    void Timer(){
    if(timer_enable_1){
    if(millis() - timer_start_1 > timer_1){
    timer_enable_1 = false;
    digitalWrite(D7, LOW);
    power_rate_1 = 0;
    enable_1 = false;
    }
    }
    if(timer_enable_2){
    if(millis() - timer_start_2 > timer_2){
    timer_enable_2 = false;
    digitalWrite(D6, LOW);
    power_rate_2 = 0;
    enable_2 = false;
    }
    }
    }

    Пара слов о скетче.

    1. Наш скетч периодически опрашивает датчики. Показания каждого датчика заносятся в массив на 10 значений, после чего вычисляется среднее арифметическое (для большей точности можно вычислять медиану). Соотвественно эти данные о текущих показаниям могут быть в любой момент получены от него.

    2. Показания датчиков один раз в час (период можно регулировать) заносятся в массив из 100 значений. И в любой момент этот массив по запросу может быть выдан. Это история показаний датчиков. 100 значений по часу, чуть более 4 суток получается.

    3. Алгоритм работы собственно конфорок. Вычисляется время включения и выключения с учетом установленной мощности, установленного цикла. К примеру, длительноть рабочего цикла у нас установлена 10 секунд, а мощность 10%. Следовательно конфорка включится на 1 секунду, затем выключится на 9 секунд и далее по кругу.

    4. Запоминаются время включения (для последующего отображения времени готовки) и также устанавливается таймер с обратным отсчетом, о нем позже.

    5. Все эти данные могут быть получены с помощью GET-запроса. Ну например, наберем в адресной строке браузера домашнего компьютера следующий адрес:

    192.168.0.100/set?info, в ответ получим строку в CSV-формате следующего вида

    0|0|0|0|0|0|0|0|3600000|5.00

    Числа, разделенные вертикальной чертой, каждое из которых отображает данные о текущем режиме (мощность первой конфорки, время ее работы, таймер, то же для второй, период истории, установленный цикл).

    192.168.0.100 — это локальный адрес нашего Wemos D1 mini, он назначается роутером и узнать его можно при подключении Wemos D1 mini к компьютеру в мониторе порта.

    192.168.0.100/set?klimat, нам вернет 751.26|21.69|49.16|23.68 — показания датчиков.

    192.168.0.100/set?history нам вернет строку длиной почти в 4 тыс. символов примерно в таком виде:

    746.28|23.69|54.19|26.14|133351518@746.21|25.09|52.78|25.34|132751517@…

    Это показания датчиков с отметкой времени каждого (в ms назад от текущего момента).

    Управление будет происходить запросами в виде

    192.168.0.100/set?power_1=50 — этот запрос установит мощность первой конфорки на 50%.

    Остальные запросы можно посмотреть в скетче.

    Вопросы по скетчу можете задавать в комментариях или в личке, отвечу. Зачем там строка длиной в 4500 нулей? Это старая длинная история поиска путей стабильности работы Wemos. К слову, успешная. Wemos немножко неправильно работает с памятью при наращивании строк, и вот эти нули решают эту проблему.

    Итак, уже все работает, можем получать информацию и отдавать команды. Осталось только выбрать UI-среду, которая будет делать это чуть более элегантно, чем строчки в браузере. Ну тут у кого к чему душа лежит. Можно сделать локальную веб-страничку с Ajax-запросами. Можно накодить простенькую windows-прогу в WPF. Но разумеется удобнее всего будет смартфон. Я выбрал конечно последнее, тем более, что немножко поверхностно могу кодить на Jave для Android. Кто не может, можете воспользоваться потрясной штукой MIT App Inventor 2. Эта среда позволяет писать проги для Андроида прям на коленке, без знания языка, просто на алгоритмах. В своем прошлом обзоре я пользовался именно ею и подробно о ней рассказывал. Причем результат визуально будет мало отличаться от «взрослой» проги, написанной в Android Studio.

    Итак, написанная за пару вечеров программка выглядит так:

    Подключаем электропечь к андроиду с помощью Wemos D1 mini

    На главном экране вверху находятся кнопки выбора конфорки. Поскольку реле подключены к дальней левой и правой ближней, кнопки расположены именно в таком порядке. Кроме этого они служат индикатором текущего режима (меняют цвет от зеленого к красному в зависимости от установленной мощности, белые — если выключены). Для каждой конфорки все параметры (мощность, время, таймер) отдельные.

    Ниже время, прошедшее с момента включения конфорки. Удобно сразу видеть, сколько готовится блюдо, без запоминания когда включил и т.д.

    Еще ниже таймер. Выполняет 4 функции:

    — во-первых, устанавливается ползунком,

    — во-вторых, ведет обратный отсчет, показывая сколько осталось,

    — в-третьих, выключает конфорку по истечении времени,

    — в-четвертых, оповещает хозяина звуковым сигналом и вибрацией по окончании отсчета.

    Ниже ползунок для установки мощности в процентах. Еще ниже кнопки для быстрой установки стандартных значений. К примеру, после пары недель использования мы поняли, что суп приятно кипит на 7% мощности, а мясо имеет идеальную золотистую корочку при 53% жарки, можем назначить на кнопки эти предустановленные значения в настройках:

    Подключаем электропечь к андроиду с помощью Wemos D1 mini

    Там же можно регулировать остальные параметры (рабочий цикл, частоту сохранения истории, IP адрес).

    В принципе по печке это и все.

    В верхнем эпп-баре есть еще пара кнопок (кроме кнопки настройки), средняя ведет нас к этому экрану (текущие показания датчиков):

    Подключаем электропечь к андроиду с помощью Wemos D1 mini

    Температуры две (цифровых), т.к. у нас два датчика, которые ее отображают.

    А левая кнопка ведет нас в историю показаний:

    Подключаем электропечь к андроиду с помощью Wemos D1 mini

    Вот график с давлением действительно полезная штука. Тенденция его изменения очень хорошо кореллируется с самочувстсвием.

    Пара слов об опыте использования. Супер, что сказать, даже лучше, чем мне казалось вначале. Во-первых, возможность выставить очень точно силу огня, которая будет поддерживаться идеально. Обычные регуляторы так не могут. У них меньше градаций, плюс каждый имеет свой разброс. Угадать не просто. Для блюд, которые хорошо выкипают, это важно.

    Во-вторых, время и таймеры. Честно, лично я ленюсь каждый раз засекать время готовки, приходится делать на глаз, пробуя. Плюс частенько поставил, зачитался интересным обзором на Mysku и забыл. А таймер всегда напомнит и выключит огонь. Плюс иногда бывает нужно готовить блюдо несколько часов. Можно поставить и отлучиться в магазин, не переживая, что задержишься.

    Дискомфорта от доставания телефона для включения конфорки нет, быстро привыкаешь. Не так это часто делается.

    Ну конечно мне тоже пришла в голову мысль попробовать использовать пищевой температурный датчик. Опускаем его в кастрюльку с пельменями и следим за температурой воды, как только температура приближается к 95-99 градусам, ставим мощность на слабый огонь, пельмени никуда не убегают. Профит. Может как-нибудь попробую. Вроде бы попадались такие датчики в продаже.

    Спрашивайте, что не понятно, с радостью отвечу. Спасибо за внимание.

    Вот так на меня смотрела кошка, пока я все это делал:

    Подключаем электропечь к андроиду с помощью Wemos D1 mini

Понравилась статья? Поделиться с друзьями:
Agkz.ru - блог файлообменника
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: