Добавляем WiFi к монитору качества воздуха: измеритель CO2 для умного дома

  • Tutorial
Измерители CO₂ от Даджет уже снискали некоторую популярность из-за своей доступности и достаточно низкой цены(да, до десяти тысяч за NDIR-измеритель это еще бюджетно).
И вот когда я в один прекрасный момент задумался о мониторинге в своем доме не только температуры и влажности, но еще и количества углекислого газа, я сразу же вспомнил об этой компании и ее приборах.



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

Итак, решено: берем монитор CO₂ и прикручиваем к нему WiFi в виде ESP8266.

WiFi Inside


Пациент готов к операции:



Для вскрытия надо вытащить 4 резиновых заглушки:



И выкрутить винты, скрывающиеся под ними. После этого можно осторожно разъединить две части корпуса(например пластиковой карточкой):



Осторожно — потому что внутри они соединены трубкой, которую надо аккуратно отцепить и засунуть внутрь корпуса, чтобы не мешалась:



На нижней части платы расположены 4 контактных отверстия:



Люди, знакомые с электроникой, поймут их назначение по буквам рядом с ним. Остальные поймут это из моего объяснения: V (voltage) — питание, D(data) — данные, С(clock) — синхронизация, G(ground) — земля.
G, он же GND, он же «земля» — нулевая точка, от которой отсчитывается напряжение питание(то, которое V) и уровни сигналов данных. В обывательской практике можно сказать, что G — это «минус», а V — это «плюс», как в батарейках. Оно даже будет правдой… пока не появится еще одно напряжение, после чего условности вроде «минуса» полетят в тартарары.

С, он же clock, он же тактовый, он же синхросигнал — специальный сигнал, который указывает принимающей стороне, когда надо считывать сигнал с линии данных(которая D).
В отличии асинхронных протоколов(типа UART/RS-232), где такого сигнала нет, и синхронизация строится на точном указании одинаковой частоты(=скорости) на передающей и принимающей стороне(все эти 1200, 9600, 115200 бод), в синхронном протоколе есть отдельная линия, смена уровня на которой означает, что приемник должен измерить состояние линии данных поняв, какой бит передается в текущий момент.
Плюсом синхронного протокола является нечувствительность к разнице тактирования устройств(можно хоть ручками набирать байты, если не ограничений по времени), минусом — необходимость отдельного провода. В принципе, при одинаковой частоте передачи, можно разбирать синхронную передачу и без тактового сигнала, но такими извращениями мы страдать не будем.

Цепляемся осциллографом на контакты и видим посылки с данными:



Приближаем, и вот уже можем разглядеть отдельные биты:



Можем даже расшифровать сообщение, но не будем. Нам важно понять, что он действительно что-то отправляет, чтобы потом не думать «а почему у меня данные не приходят» по причине их отсутствия.

Вместо осциллографа припаиваем и клеим термоклеем платку с ESP8266:



Подключаем ее по UART к компьютеру(на фото два провода, без земли, потому что измеритель питается от того же ноута) и начинаем писать код.



Исходники

Пишется код в среде Arduino c включенной поддержкой ESP8266(как ее включить, можно прочитать вот тут). Как нажимать кнопочку для прошивки, думаю, разберетесь сами, или с помощью esp8266.ru.

Сам проект состоит из трех файлов: файла проекта, и подключенной библиотеки за авторством fedorro, который в свою очередь, использовал наработки отсюда.

Код я спрячу под спойлер, даже не смущать неокрепшие умы
Файл первый, CO2_meter.ino:

#define PIN_CLOCK  14 // Пин, к которому подключен контакт "С" — тактовый сигнал
#define PIN_DATA   12 // Пин, к которому подключен контакт "D" — данные

#include <ESP8266WiFi.h> 
#include <ESP8266WebServer.h>
#include "mt8060_decoder.h"

const char* ssid = "MikroTik-951"; //Имя сети
const char* password = "FAKEPASSWORD"; //Пароль сети
String co2_value = ""; //Значение содержания углекислоты в ppm
String tmp_value = ""; //Значение температуры в градусах цельсия
String hum_value = ""; //Значение влажности воздуха в процентах
int error_count = 0; //Счетчик ошибок контрольной суммы(кстати, можно не считать, неделями работает без ошибок)


ESP8266WebServer server(80); //Создаем обьект сервера

void setup()
{
  Serial.begin(115200); //Настраиваем UART
  WiFi.begin(ssid, password); //Подключаемся к WiFi

  while (WiFi.status() != WL_CONNECTED) 
  {
    delay(500);
    Serial.print("."); // Усердно показываем в UART, что мы заняты делом
  }
  Serial.println("");
  Serial.print("WiFi connected, IP ");
  Serial.println(WiFi.localIP());

  server.on("/co2", co2_show); // Устанавливаем адреса страниц и функции, этим адресам соотвествующие
  server.on("/tmp", tmp_show);
  server.on("/hum", hum_show);
  server.on("/json", json_show);
  server.onNotFound(NotFound_show); // Главная страница
  server.begin();

  pinMode(PIN_CLOCK, INPUT); //Настраиваем порты на вход
  pinMode(PIN_DATA, INPUT); //Настраиваем порты на вход
  attachInterrupt(digitalPinToInterrupt(PIN_CLOCK), interrupt, FALLING); //Включаем прерывание на пине с тактовым сигналом
}


void interrupt() // По каждому прерыванию начинаем собирать данные
{
  bool dataBit = (digitalRead(PIN_DATA) == HIGH);
  unsigned long ms = millis();
  
  mt8060_message* message = mt8060_process(ms, dataBit); //Отправляем текущее время и текущий бит в функцию, взамен получаем восхитительное ничего, если битов еще не набралось до полного сообщение, и расшифрованный пакет, если битов достаточно.

  if (message) { //если в ответ получен пакет
    if (!message->checksumIsValid) //то проверяем, правильно ли рассчитана контрольная сумма
    {
      error_count++;
    }
    else // и если правильно...
    {
      switch (message->type) //...то в зависимости от типа пакета...
      {
        case HUMIDITY: 
          hum_value = String((double)message->value / 100, 0); // сохраняем значение влажности
          Serial.print("HUM:"); 
          Serial.println(hum_value); // Выводим в UART
          break;

        case TEMPERATURE:
          tmp_value = String((double)message->value / 16 - 273.15, 1); // конвертируем и сохраняем значение температуры
          Serial.print("TMP:"); // Смотрите-ка! Сиськи! -> (. )(. )
          Serial.println(tmp_value); // Выводим в UART
          break;

        case CO2_PPM:
          co2_value = String(message->value, DEC); // сохраняем значение количества CO₂
          Serial.print("CO2:");
          Serial.println(co2_value); // Выводим в UART
          break;

        default:
          break;
      }
    }
  }
}

void co2_show() { //Функция, выводящая CO₂ простым текстом
  server.send(200, "text/plain", co2_value);
}

void tmp_show() { //Функция, выводящая температуру простым текстом
  server.send(200, "text/plain", tmp_value);
}

  void hum_show() { //Функция, выводящая влажность простым текстом
  server.send(200, "text/plain", hum_value);
}

void NotFound_show() { //Функция, выводящая красивую стартовую страницу с кнопочками
  String form = "<!DOCTYPE html><html lang=\"en\"><head><meta http-equiv=\"Content-Type\" content=\"text/html\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\"><title>Dadget МТ8060 CO₂ monitor</title><style>.c{text-align: center;} div,input{padding:5px;font-size:1em;} input{width:95%;} body{text-align: center;font-family:verdana;} button{border:0;border-radius:0.3rem;background-color:#1fa3ec;color:#fff;line-height:2.4rem;font-size:1.2rem;width:100%;} .q{float: right;width: 64px;text-align: right;}</style><style type=\"text/css\"></style></head><body><div style=\"text-align:left;display:inline-block;min-width:260px;\"><h1>Dadget МТ8060 CO₂ monitor</h1><form action=\"/co2\" method=\"get\"><button>CO₂ value ([co2] ppm now)</button></form><br><form action=\"/tmp\" method=\"get\"><button>Temperature value ([tmp]°С now)</button></form><br><form action=\"/hum\" method=\"get\"><button>Humidity value ([hum]% now)</button></form><br><form action=\"/json\" method=\"post\"><button>JSON(all values)</button></form></div></body></html>";
  form.replace("[co2]", co2_value); //подставляем текущие значения
  form.replace("[hum]", hum_value);
  form.replace("[tmp]", tmp_value);
  server.send(200, "text/html", form); //отправляем форму клиенту
}

void json_show() { //Функция, выводящая все данные в виде JSON
  String json = "[{\"co2\":"; //Формируем строку c JSON данными
  json += co2_value;
  json += ",\"tmp\":";
  json += tmp_value;
  json += ",\"hum\":";
  json += hum_value;
  json += ",\"serial\":";
  json += ESP.getChipId();
  json += ",\"errors\":";
  json += error_count;
  json += ",\"uptime_min\":";
  json += String(millis()/60000);
  json += "}]";

  server.send(200, "application/json", json); //Отправляем
}

void loop()
{
  server.handleClient(); //Ждем подключения клиентов по HTTP
}

Файл второй, mt8060_decoder.cpp:

// Based on https://github.com/fe-c/MT8060-data-read code
// All rights for reading code owned https://geektimes.ru/users/fedorro/
// and https://github.com/revspace

#include "mt8060_decoder.h"
#define MT8060_MAX_MS  2 // Таймаут по которому считаем, что началось новое сообщение
#define MT8060_MSG_LEN 5 // В одном полном сообщении 5 байт
#define MT8060_MSG_TYPE_BYTE_IDX          0
#define MT8060_MSG_VAL_HIGH_BYTE_IDX      1
#define MT8060_MSG_VAL_LOW_BYTE_IDX       2
#define MT8060_MSG_CHECKSUM_BYTE_IDX      3
#define MT8060_MSG_CR_BYTE_IDX            4
#define BITS_IN_BYTE                      8

static uint8_t buffer[MT8060_MSG_LEN]; // Буфер для хранения считанных данных
static int num_bits = 0;
static unsigned long prev_ms;

static mt8060_message _msg;
static mt8060_message *msg = &_msg;


void mt8060_decode(void) // Декодирует сообщение
{

  uint8_t checksum = buffer[MT8060_MSG_TYPE_BYTE_IDX] + buffer[MT8060_MSG_VAL_HIGH_BYTE_IDX] + buffer[MT8060_MSG_VAL_LOW_BYTE_IDX];   // Вычисление контрольной суммы
  msg->checksumIsValid = (checksum == buffer[MT8060_MSG_CHECKSUM_BYTE_IDX] && buffer[MT8060_MSG_CR_BYTE_IDX] == 0xD); // Проверка контрольной суммы
  if (!msg->checksumIsValid) {
    return;
  }
  msg->type = (dataType)buffer[MT8060_MSG_TYPE_BYTE_IDX]; // Получение типа показателя
  msg->value = buffer[MT8060_MSG_VAL_HIGH_BYTE_IDX] << BITS_IN_BYTE | buffer[MT8060_MSG_VAL_LOW_BYTE_IDX]; // Получение значения показателя
}


// Вызывается на каждый задний фронт тактового сигнала, возвращает ссылку на структуру сообщения, если оно полностью считано
mt8060_message* mt8060_process(unsigned long ms, bool data)
{
  if ((ms - prev_ms) > MT8060_MAX_MS) {
    num_bits = 0;
  }
  prev_ms = ms;

  if (num_bits < MT8060_MSG_LEN * BITS_IN_BYTE) {
    int idx = num_bits / BITS_IN_BYTE;
    buffer[idx] = (buffer[idx] << 1) | (data ? 1 : 0);
    num_bits++;

    if (num_bits == MT8060_MSG_LEN * BITS_IN_BYTE) {
      mt8060_decode(); //Декодируем сообщение
      return msg; //Возвращаем сообщение
    }
  }
  return nullptr; //Ничего не возвращаем, если сообщение не полное
}


Файл третий, mt8060_decoder.h
// Based on https://github.com/fe-c/MT8060-data-read code
// All rights for reading code owned https://geektimes.ru/users/fedorro/
// and https://github.com/revspace

#include <stdint.h>
#include <stdbool.h>

typedef enum
{
    HUMIDITY    = 0x41,
    TEMPERATURE = 0x42,
    CO2_PPM     = 0x50,
} dataType;

typedef struct {
    dataType type;
    uint16_t value;
    bool checksumIsValid;
} mt8060_message;

mt8060_message* mt8060_process(unsigned long ms, bool data);



Так же, код можно посмотреть на моем GitHub. Пулл-реквесты приветствуются, как и подсказки в комментариях, как можно сделать лучше!

Запускаем, заходим на страничку устройства…



Работает! Приводим провода в порядок, находим для платы свободное место в корпусе:



Закрепляем каплей термоклея, и вот, операция закончена, остается зашить закрыть крышку(не забыв про трубочку), и установить в нужное место дома:



Собираем статистику


Однако, пока что ситуации «посмотрел на экран измерителя» и «посмотрел на веб-страничку» отличаются не очень сильно. Чтобы было интереснее, надо либо чем-то управлять, либо собирать статистику.

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

Для того, чтобы сделать из единичных показаний график, я воспользуюсь возможностями Logic Machine — скриптами и трендами. Конечно, все тоже самое можно сделать и на любом компьютере, но раз инструменты есть у меня под рукой, почему бы не воспользоваться.

Создаем новый Sheduled-скрипт(выполняющийся по расписанию), настраиваем его на запуск каждую минуту:



Внутри пишем что-то вроде этого:

local http = require('http')
local json = require('json')
local raw_data, code = socket.http.request('http://co2meter.lc/json') --Запрашиваем страничку. Говорим спасибо роутеру микротик за внутренние DNS-имена
if (code == 200) then --Если код ответа 200..
  local data = json.decode(raw_data) --Пытаемся декодировать ответ из json в таблицы lua
  if (data ~= nil) then --Если ответ являлся валидными json-данными... 
    if (data[1].uptime_min > 2) then --И если это не первые две минуты работы измерителя(после включения происходит "прогрев" и во время него значения могут плавать)
      grp.update('S_CO2_CO2', data[1].co2) --Записываем в объекты значения CO₂, влажности и температуры 
      grp.update('S_CO2_TMP', data[1].tmp)
      grp.update('S_CO2_HUM', data[1].hum)
    end
  end
end


Вуаля! Мы получили первые показания:



Теперь надо их превратить в симпатичные графики. Нет ничего проще(да простит меня Dadget за бессовестную рекламу нашего контроллера, я уже заканчиваю)! Trends logs —> Add new trend log:



Теперь осталось подождать недельку-другую для сбора данных, и вот они, наши графики:



Ну и конечно, самый интересный график:



Оказалось, наблюдать за уровнем CO₂ и проводить параллели между изменениями на графике и своими действиями оказалось очень интересно!
Факт №1: Газовая плита ОЧЕНЬ сильно повышает уровень CO₂.
Факт №2: При отсутствии людей и хотя бы чуть-чуть открытом окне(даже в режиме микропроветривания) уровень CO₂ быстро снижается до фоновых значений.



Факт №3: Люди в квартире(даже спящие) вносят существенный вклад в количество углекислоты. Важно открывать окна(можно в другой части квартиры) на ночь, чтобы не надышать до вредных значений.
Факт №4: Количество CO₂, выделяемое человеком, сильно зависит от его активности. Стоит проснуться и полуспящим походить по квартире, как количество углекислоты начинает расти.



Факт №5: Количество CO₂, выделяемое человеком, ОЧЕНЬ сильно зависит от его активности. И от типа активности.



Управляем вентилятором


В качестве площадки для тестирования вентиляции, управляемой по уровню CO₂, я выбрал офис. В нем уже настроено управление вентиляцией с контроллера(как именно, смотрите по предыдущей ссылке), так что мне просто оставалось настроить реакцию на повышение уровня CO₂. В LM делается это так:

Создаем новый скрипт типа Event-based(выполняемый при изменении объекта), устанавливаем в качестве объекта мониторинга объект, в который мы записывает текущее значение CO₂:



В коде скрипта пишем несложную логику, которая будет включать вентиляцию при уровне углекислоты выше 1000ppm, и выключать при уровне меньше 800, реализуя гистерезис для предотвращения частого включения-выключения вентиляции:

--Скрипт выполняет при любом изменении объекта
value = grp.getvalue("S_CO2_CO2") --Получаем значение обьекта с количеством углекислого газа
if (value > 1000) then --Если его больше, чем 1000ppm...
  grp.write('HP-7.1', true) --..включаем вентиляцию
elseif (value < 800) then --Если CO₂ меньше, чем 800ppm...
  grp.write('HP-7.1', false) --..выключаем вентиляцию
end 

Таким образом, вентиляция включится при повышении уровня CO₂ до 1000ppm, и не выключится, пока не опустит его значение до 800ppm.

Жужжит!



Ссылки:

Внутренности похожего устройства и описание протокола
Обзор прибора
Разбор прибора
Подключение измерителя к Arduino

Если вам интересны темы интернета устройств и умного дома, добро пожаловать в канал в телеграме: telegram.me/IOTandSmarthome

В течение 14 дней, со дня публикации данной статьи, вы можете приобрести «Монитор качества воздуха» с 10%-й скидкой, используя код GEEKT-MK.
Даджет 88,51
Компания
Поделиться публикацией
Никаких подозрительных скриптов, только релевантные баннеры. Не релевантные? Пиши на: adv@tmtm.ru с темой «Полундра»

Зачем оно вам?
Реклама
Комментарии 35
  • +4
    Спасибо за статью!

    П.С, Последнее фото очень пугает. Заделать трещу монтажной пеной? Остановите Землю, я сойду…
    • +3
      это похоже не на трещину, а на странно пристроенную стену к имеющейся кирпичной стене. Видать, дует хорошо.Но факт — пену надо предохранять от солнца, штукатуркой к примеру, иначе она наберет влагу, сгниет, и все ее качества пропадут.
      • 0
        Сначала она деградирует от ультрафиолета, а только потом начнет гнить. Так-то там полиуретан, и если нет солнца, он неплохо себя чувствует и при высокой влажности.
    • +1
      А что с временем на оси абсцисс?
      image
      • –1
        А что с ним?
        • +1
          Шкала на 24 часа и воспринимается как реальное время. Тем более в левом верхнем углу дата.
          В час ночи готовка. Сон в 6 утра до 11. Готовить больше не стали. Пошли гулять с 13 до 23 часов.
          • 0
            Это и есть реальное время image
            • +2
              Жить вредно, особенно так :) Боюсь увидеть график температуры за этот же период. Сон в такое жаркое время.
      • +1
        Выходит, секс не регулярный? Или это сразу за два дня договорились?)
        И да, 31 мая рабочий день. 12:00 и 14:30 Это как-то странно)))
        • +2
          В смысле, нерегулярный? ИМХО для этого недостаточно данных. Скорее всего, он регулярный, но по нескольку раз, что замечательно.

          Что до рабдней — для кого 31 мая рабочий, для кого — нерабочий. Я вот тоже когда выхожу на улицу в рабочее время, думаю — откуда все эти люди и почему они не на работе?
          • +1
            Согласен, нужно больше данных. Призываю vvzvlad раскрыть тему в следующей статье.

            А по поводу рабочего дня… есть объяснение графиком 2/2, если подумать.
        • +1
          Цена какая-то странная… Покупал точно такой же девайс почти полгода назад за 7900 — мало того, дали в подарок USB-прикуриватель. А сейчас цена уже 8950 рублей. Полгода назад доллар был в районе 80, а сейчас ниже 65. Интересно, с чем связано такое подорожание в рублях и в валюте?
          • +1
            vvzvlad, скажите пожалуйста, Вы планируете продавать версию MT8060 с полноценным USB-портом? (модель ZG1683RU)
            Радует, конечно, возможность топориком на коленке прикрутить WiFi к урезанной версии, но хочется все же полноценную, с возможностью просто подключить к компу (чтобы и питание и данные были по USB).
            • 0
              Это, боюсь, не ко мне вопрос, а к сотрудникам даджет-а. Думаю, кто-нибудь из них вам ответит.
            • +1
              А есть статистика по сексу стабильности этой версии ESP8266 без дополнительной обвязки? А то я такую упаковал, как пугали — вся в резисторах и конденсаторах, смотреть страшно. Теперь думаю: или и так сойдет?
              • +2
                7 месяцев назад слепил из esp метеостанцию. Тоже начитался, что нужны фильтрующие кондеры и подобная ерунда, но я ничего ставить не стал. Припаял только подтягивающие резюки к датчикам и всё. Питается плата от обычного адаптера для мобильников, напряжение в сети 240 вольт и проблем за эти 7 месяцев не было вообще. Но, я видел скриншоты графиков температуры с метеостанций на основе esp, где видно, что в момент включения в доме, например, утюга или пылесоса показания резко менялись.
                • +2
                  А есть статистика по сексу стабильности этой версии ESP8266 без дополнительной обвязки? А то я такую упаковал, как пугали — вся в резисторах и конденсаторах, смотреть страшно. Теперь думаю: или и так сойдет?


                  Без одного резистора просто не запустится, без второго есть риск, что при перезагрузке уйдёт в режим прошивки. У меня без конденсаторов живут есп в количестве трёх штук(датчик co2, стиральная машинка, освежитель в туалете), но от хорошего БП. Работает все это уже месяца 4, намертво не зависало ни разу. Может быть, само перезагружается, не смотрел точно аптаймы. У датчика CO2 аптайм в среднем в неделю, но по моей вине — постоянно из розетки дергаю.
                  • 0
                    Тем временем на модули с обвязкой, которые легко находятся по запросу «nodemcu» на Ali, цены упали ниже 200 рублей / шт.
                    • 0
                      Это да. Но тут такое дело: я несколько комплектов из модуля и переходника купил больше полугода назад, когда все еще не так радужно было. Не выкидывать же теперь.
                  • +1
                    А кто нибудь в курсе, можно ли сделать такое же на их маленьком детекторе MT8057?
                    • +1
                      Простите, не понимаю
                      Зачем покупать компактный модуль для SMD пайки и лепить его на огромный переходник в DIP?
                      Эти модули сразу продаются с PLS разъемами
                      • +1
                        Ну это как раз понятно. Это хитрый переходник для макетирования. Там уже распаян минимум обвязки и с оборота должны быть (у моих — есть) площадки для стабилизатора (самого стабилизатора нет), питающего ESP8266.

                        Продается это дело комплектами, поэтому покупатель сам решает, что делать: то ли использовать модуль, как есть, то ли припаять на переходник и не мучиться.
                        • 0
                          Зачем покупать компактный модуль для SMD пайки и лепить его на огромный переходник в DIP?
                          Ммм. А что не так? Без платы неудобно — там подтяжка нужна на двух контактах нужна, и перемычка ещё на одном. Плюс на обратной стороне платы место под стабилизатор, если от 5в питать. Правда, оно под какой-то китайский, похоже, стаб, и обычные туда встают с костылями. Но встают.
                          Покупать два разных версии модуля не хочу — проще купить универсальный модуль, который можно хоть в разработанную плату запаять, хоть в такую простую отладочную.
                          Надо бы сделать свою макетку, чтобы была и габаритами поменьше, и с кнопками под RESET/FLASH, но это пока сделается…

                          Эти модули сразу продаются с PLS разъемами
                          Это какие? С двумя выведенными GPIO? Или вы про белую плату, которая с маркировкой Dev?
                          • 0
                            Там выводы под стаб местами перепутаны. Уже есть версии в продаже исправленные.
                        • 0
                          Местами напоминает рисование совы: вот мы припаялись, подключили RS232, а потом уже сразу зашли браузером )
                          P.S. Logic Machine очень крут, особенно софт! Жалко, что на сайте нет цен.
                          • +3
                            Не RS232, а UART. У них напряжения отличаются — у UART обычно подразумевается 5/3.3 вольт, а у RS232 двухполярное, да еще и высокое — до 15 вольт.

                            Между ними было написание кода. Про код вообще трудно писать, разве что слепками, как я делал в статье про Pebble. Но тут так не получилось, потому что часть кода не моя, а остальная собиралась методом копипаста. Кроме того, я не очень горю желанием рассказывать, как в IDE Arduino писать код, не нравится она мне. Остановился на относительно подробно комментированном коде.
                            На самом деле, состояние «припаялись» превращается в «зашли браузером» десятком строчек:

                            #include <ESP8266WiFi.h> 
                            #include <ESP8266WebServer.h>
                            const char* ssid = "MikroTik-951"; 
                            const char* password = "FAKEPASSWORD"; 
                            ESP8266WebServer server(80); 
                            void setup()
                            {
                              WiFi.begin(ssid, password); 
                              server.onNotFound(html); 
                              server.begin();
                            }
                            
                            void html() 
                            {
                              server.send(200, "text/html", "Hello world"); 
                            }
                            
                            void loop()
                            {
                              server.handleClient();
                            }
                            
                          • –1
                            «Приближаем...» о режиме развертки осциллографа.
                            Вот такие фразы сразу выдают уровень статьи.
                            • +1
                              В данном случае я действительно «приближал» — захватил несколько посылок, а потом просто увеличил масштаб по времени, благо разрешения и памяти хватило. Если бы вы внимательно посмотрели на фотографии, вы бы увидели в верхней части экрана осциллографа индикатор масштаба.
                              Но в общем-то, не вижу особой проблемы в использовании термина «приблизить» в смысле изменения частоты развертки. Хотя, что тоже выдает уровень комментария, в цифровом осцилле никакого блока развертки уже нет, а есть только частота дискретизации.
                            • +1
                              Вопрос vvzvlad.
                              Там на фотках виднеются корпуса от Noolite. Неужели кто-то еще занимается адаптированием устройств Noolite через ESP на WiFi?
                              Если так, то как реализована проверка состояния вкл/выкл, в том числе и для RGB?
                              • 0
                                Нет, они там просто так валяются, с другого проекта. У меня сейчас работают только их пульты через USB-приемник для управления домом.
                                Обещают прошивку для шлюза одновременно с приемом сигналов с пультов и с передачей команд блокам. Но и в этом случае состояние блока будет недоступно, увы.
                              • 0
                                Хорошая статья, спасибо! Хочу тоже заняться так так сделать.
                                • 0
                                  А есть библиотека для подключения к Raspberry Pi?
                                  • 0
                                    Попытался поженить результат данной статьи с отсылкой данных в любое облачко. Цикл показаний примерно 5 секунд, если верить консоли, я на время отсылки данных попытался выключать прерывания (мне достаточно и 5 минут между), а затем включать. Ничего не получилось, http-запрос не срабатывает, хотя web-сервер работает исправно.
                                    • 0
                                      А код покажете?
                                      • +1
                                        Да, конечно.
                                        http://pastebin.com/6P3mbuFJ
                                        Из пасты убрал приватную инфу.

                                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                    Самое читаемое