image


Про измерение CO2 и его важность на Geektimes было уже немало публикаций (ссылки в конце статьи). Здесь же хочу описать проект компактного монитора уровня CO2, а также температуры, влажности и давления с Wi-Fi, обновлением прошивки по воздуху и интерфейсом в мобильном приложении. Сердца системы модуль на базе esp8266, сенсор CO2 MH-Z19 и фреймворк esp8266-arduino. И так, включим устройство в USB-розетку:


image


Cперва оно попытается подключиться к сохраненной ранее сети и успешно выполнив подключение, начинает работу. Если же wifi сеть не обнаружится, то монитор загрузится в режиме ожидания настройки и поднимет точку доступа. Подключившись к ней и открыв в браузере http://192.168.4.1 можно указать данные реальной сети, а также ключ для подключения к серверу и имя устройства.


image


На сервере и для мобильного клиента использован открытый проект Blynk. Он уже упоминался пару раз на Geektimes. Это opensource сервер, который имеет библиотеки для разных встраиваемых систем и позволяет в несколько строчек подключить общение со сторонним сервисом. Можно установить его на свой сервер, например запустив docker-контейнер, a можно использовать и публичный сервер разработчика.


Интерфейс для blynk строится из готовых кирпичиков в мобильном приложении доступном для iOS и Android. Web-интерфейса, к сожалению нет. Через него можно посмотреть историю измерения всех параметров, настроить нотификации или web hook на по условию (здесь — превышению уровня CO2), обновить прошивку и сброситься к настройкам по умолчанию.


Blynk позволяет распространять приложения через внушительных размеров QR-код, в котором сохранена конфигурация всех модулей.


QR-код приложения, просканируйте приложением Blynk

image


image


Как собрать подобное устройство?


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


Компонент Поисковая фраза Ориентировочная цена
Esp-12 NodeMCU модуль* esp8266 nodemcu cp2102 $3.50
Датчик CO2 mh-z19 mh-z19 $22
Датчик давления**,*** bmp280 $1
Датчик температуры и влажности**,*** gy-21 SI7021 i2c $2.2
Экран 0.96" 128x64 i2c OLED blue $2.7
Провода dupont female-female 10cm $1
3д-печать корпуса - $8
Итого: $40.4

* — На китайском рынке существуют две версии модуля NodeMCU. Они отличаются в первую очередь USB-UART преобразователем cp2102 и ch340g, но и размером — версия с ch340g шире на 3 мм и уже не влезет в этот корпус. Также, версия с cp2102 может быть интереснее, потому что у этого преобразователя нет проблем с драйверами под любую операционку.
** — В текущей версии использовался bmp-085, который сейчас уже не купить. Но модули с bmp-280 имеют те же размеры и все, что нужно сделать, это заменить используемую библиотеку на https://github.com/adafruit/Adafruit_BMP280_Library — все методы у них одинаковые.
*** — Вместо пары датчиков bmp280+si7021, можно использовать один bme280, который измеряет все три показателя: температуру, влажность и давление. На aliexpress его можно найти за $3.5


Корпус


Хотелось сделать с одной стороны устройство из готовых модулей, с другой не хотелось делать его размером с буханку хлеба. Для этого в Tinkercad был нарисован корпус пригодный для 3д-печати. Большая проблема tinkercad в том, что очень тяжело вносить изменения в уже готовые проекты. Если бы я начинал сейчас, то воспользовался бы openSCAD


image


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


image


Недостаток такой плотной компановки в том, что тепло от микроконтроллера и dc-dc преобразователя нагревают воздух внутри на ~3 градуса выше реальной температуры, это же вредит точности показаний влажности. С другой стороны это создает конвекцию, которая обновляет воздух в сенсоре CO2 быстрее.


Отчасти эту проблему можно решить, поработав над потреблением микроконтроллера, например реже передавать данные по сети.


Подключение


Электрическая схема очень проста — датчик давления, датчик температуры и влажности и дисплей питаются от 3.3в и подключаются через двухпроводной интерфейс I2C. Он позволяет подключать все устройства параллельно: SDA каждого устройства к ножке D1 (GPIO5), а SCL — к ножке D2 (GPIO4)


Датчик CO2 питается от 5в (в нашем случае Vin — питание от USB входа) и подключается через UART. Для этого используются ноги D7 (GPIO13) — RX (который подключается к TX сенсора) и D8 (GPIO15) — TX (который подключается к RX сенсора)


image


Программная часть


Все файлы проекта были разработаны в среде разработки PlatformIO и лежат на Github-e.


Код прошивки, чтобы не ходить на Github
#include <FS.h>
#include <Arduino.h>
#include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino

// Wifi Manager
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>         //https://github.com/tzapu/WiFiManager

// HTTP requests
#include <ESP8266HTTPClient.h>

// OTA updates
#include <ESP8266httpUpdate.h>
// Blynk
#include <BlynkSimpleEsp8266.h>

// JSON
#include <ArduinoJson.h>          //https://github.com/bblanchon/ArduinoJson

// GPIO Defines
#define I2C_SDA 5 // D1 Orange
#define I2C_SCL 4 // D2 Yellow

// Humidity/Temperature SI7021
#include <SI7021.h>
SI7021 si7021;

#include <Wire.h>

// Pressure and Temperature
#include <Adafruit_BMP085.h>

// Use U8g2 for i2c OLED Lib
#include <SPI.h>
#include <U8g2lib.h>
U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, I2C_SCL, I2C_SDA, U8X8_PIN_NONE);
byte x {0};
byte y {0};

// Handy timers
#include <SimpleTimer.h>

// CO2 SERIAL
#define DEBUG_SERIAL Serial1
#define SENSOR_SERIAL Serial

byte cmd[9] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};
unsigned char response[7];

// Pressure and temperature
Adafruit_BMP085 bme;

// Blynk token
char blynk_token[33] {"Blynk token"};
char blynk_server[64] {"blynk-cloud.com"};
const uint16_t blynk_port {8442};

// Device Id
char device_id[17] = "Device ID";
const char fw_ver[17] = "0.1.0";

// Handy timer
SimpleTimer timer;

// Setup Wifi connection
WiFiManager wifiManager;

// Network credentials
String ssid { "ku_" +  String(ESP.getChipId())};
String pass {"ku_" + String(ESP.getFlashChipId()) };

//flag for saving data
bool shouldSaveConfig = false;

// Sensors data
int t {-100};
int p {-1};
int h {-1};
int co2 {-1};

char loader[4] {'.'};

//callback notifying the need to save config
void saveConfigCallback() {
        DEBUG_SERIAL.println("Should save config");
        shouldSaveConfig = true;
}

void factoryReset() {
        wifiManager.resetSettings();
        SPIFFS.format();
        ESP.reset();
}

void printString(String str) {
        DEBUG_SERIAL.println(str);
}

void readCO2() {
        // CO2
        bool header_found {false};
        char tries {0};

        SENSOR_SERIAL.write(cmd, 9);
        memset(response, 0, 7);

        // Looking for packet start
        while(SENSOR_SERIAL.available() && (!header_found)) {
                if(SENSOR_SERIAL.read() == 0xff ) {
                        if(SENSOR_SERIAL.read() == 0x86 ) header_found = true;
                }
        }

        if (header_found) {
                SENSOR_SERIAL.readBytes(response, 7);

                byte crc = 0x86;
                for (char i = 0; i < 6; i++) {
                        crc+=response[i];
                }
                crc = 0xff - crc;
                crc++;

                if ( !(response[6] == crc) ) {
                        DEBUG_SERIAL.println("CO2: CRC error: " + String(crc) + " / "+ String(response[6]));
                } else {
                        unsigned int responseHigh = (unsigned int) response[0];
                        unsigned int responseLow = (unsigned int) response[1];
                        unsigned int ppm = (256*responseHigh) + responseLow;
                        co2 = ppm;
                        DEBUG_SERIAL.println("CO2:" + String(co2));
                }
        } else {
                DEBUG_SERIAL.println("CO2: Header not found");
        }

}

void sendMeasurements() {
        // Read data
        // Temperature
        float tf = si7021.getCelsiusHundredths() / 100.0;
        float t2f =bme.readTemperature();
        t = static_cast<int>((tf + t2f) / 2);

        // Humidity
        h = si7021.getHumidityPercent();

        // Pressure (in mmHg)
        p = static_cast<int>(bme.readPressure() * 760.0 / 101325);

        // CO2
        readCO2();

        // Send to server
        Blynk.virtualWrite(V1, t);
        Blynk.virtualWrite(V2, h);
        Blynk.virtualWrite(V4, p);
        Blynk.virtualWrite(V5, co2);

        // Write to debug console
        printString("H: " + String(h) + "%");
        printString("T: " + String(t) + "C");
        printString("P: " + String(p) + "mmHg");
        printString("CO2: " + String(co2) + "ppm");
}

void loading() {
        long unsigned int count {(millis() / 500) % 4};
        memset(loader, '.', count);
        memset(&loader[count], 0, 1);
}

void draw() {
        u8g2.clearBuffer();

        // CO2
        if (co2 > -1) {
                char co2a [5];
                sprintf (co2a, "%i", co2);

                u8g2.setFont(u8g2_font_inb19_mf);
                x = (128 - u8g2.getStrWidth(co2a))/2;
                y = u8g2.getAscent() - u8g2.getDescent();
                u8g2.drawStr(x, y, co2a);

                const char ppm[] {"ppm CO2"};
                u8g2.setFont(u8g2_font_6x12_mf);
                x = (128 - u8g2.getStrWidth(ppm)) / 2;
                y = y + 2 + u8g2.getAscent() - u8g2.getDescent();
                u8g2.drawStr(x, y, ppm);
        } else {
                loading();
                u8g2.setFont(u8g2_font_inb19_mf);
                x = (128 - u8g2.getStrWidth(loader)) / 2;
                y = u8g2.getAscent() - u8g2.getDescent();
                u8g2.drawStr(x, y, loader);
        }

        // Cycle other meauserments
        String measurement {"..."};
        const char degree {176};

        // Switch every 3 seconds
        switch((millis() / 3000) % 3) {
        case 0:
                if (t > -100) { measurement = "T: " + String(t) + degree + "C"; }
                break;
        case 1:
                if (h > -1) { measurement = "H: " + String(h) + "%"; }
                break;
        default:
                if (p > -1) { measurement =  "P: " + String(p) + " mmHg"; }
        }

        char measurementa [12];
        measurement.toCharArray(measurementa, 12);

        u8g2.setFont(u8g2_font_9x18_mf);
        x = (128 - u8g2.getStrWidth(measurementa))/2;
        y = 64 + u8g2.getDescent();
        u8g2.drawStr(x, y, measurementa);

        u8g2.sendBuffer();
}

void drawBoot(String msg = "Loading...") {
        u8g2.clearBuffer();
        u8g2.setFont(u8g2_font_9x18_mf);
        x = (128 - u8g2.getStrWidth(msg.c_str())) / 2;
        y = 32 + u8g2.getAscent() / 2;
        u8g2.drawStr(x, y, msg.c_str());
        u8g2.sendBuffer();
}

void drawConnectionDetails(String ssid, String pass, String url) {
        String msg {""};
        u8g2.clearBuffer();

        msg = "Connect to WiFi:";
        u8g2.setFont(u8g2_font_7x13_mf);
        x = (128 - u8g2.getStrWidth(msg.c_str())) / 2;
        y = u8g2.getAscent() - u8g2.getDescent();
        u8g2.drawStr(x, y, msg.c_str());

        msg = "net: " + ssid;
        x = (128 - u8g2.getStrWidth(msg.c_str())) / 2;
        y = y + 1 + u8g2.getAscent() - u8g2.getDescent();
        u8g2.drawStr(x, y, msg.c_str());

        msg = "pw: "+ pass;
        x = (128 - u8g2.getStrWidth(msg.c_str())) / 2;
        y = y + 1 + u8g2.getAscent() - u8g2.getDescent();
        u8g2.drawStr(x, y, msg.c_str());

        msg = "Open browser:";
        x = (128 - u8g2.getStrWidth(msg.c_str())) / 2;
        y = y + 1 + u8g2.getAscent() - u8g2.getDescent();
        u8g2.drawStr(x, y, msg.c_str());

        // URL
        // u8g2.setFont(u8g2_font_6x12_mf);
        x = (128 - u8g2.getStrWidth(url.c_str())) / 2;
        y = y + 1 + u8g2.getAscent() - u8g2.getDescent();
        u8g2.drawStr(x, y, url.c_str());

        u8g2.sendBuffer();
}

bool loadConfig() {
        File configFile = SPIFFS.open("/config.json", "r");
        if (!configFile) {
                DEBUG_SERIAL.println("Failed to open config file");
                return false;
        }

        size_t size = configFile.size();
        if (size > 1024) {
                DEBUG_SERIAL.println("Config file size is too large");
                return false;
        }

        // Allocate a buffer to store contents of the file.
        std::unique_ptr<char[]> buf(new char[size]);

        // We don't use String here because ArduinoJson library requires the input
        // buffer to be mutable. If you don't use ArduinoJson, you may as well
        // use configFile.readString instead.
        configFile.readBytes(buf.get(), size);

        StaticJsonBuffer<200> jsonBuffer;
        JsonObject &json = jsonBuffer.parseObject(buf.get());

        if (!json.success()) {
                DEBUG_SERIAL.println("Failed to parse config file");
                return false;
        }

        // Save parameters
        strcpy(device_id, json["device_id"]);
        strcpy(blynk_token, json["blynk_token"]);
}

void configModeCallback (WiFiManager *wifiManager) {
        String url {"http://192.168.4.1"};
        printString("Connect to WiFi:");
        printString("net: " + ssid);
        printString("pw: "+ pass);
        printString("Open browser:");
        printString(url);
        printString("to setup device");

        drawConnectionDetails(ssid, pass, url);
}

void setupWiFi() {
        //set config save notify callback
        wifiManager.setSaveConfigCallback(saveConfigCallback);

        // Custom parameters
        WiFiManagerParameter custom_device_id("device_id", "Device name", device_id, 16);
        WiFiManagerParameter custom_blynk_server("blynk_server", "Blynk server", blynk_server, 64);
        WiFiManagerParameter custom_blynk_token("blynk_token", "Blynk token", blynk_token, 34);
        wifiManager.addParameter(&custom_blynk_server);
        wifiManager.addParameter(&custom_blynk_token);
        wifiManager.addParameter(&custom_device_id);

        // wifiManager.setTimeout(180);
        wifiManager.setAPCallback(configModeCallback);

        if (!wifiManager.autoConnect(ssid.c_str(), pass.c_str())) {
                DEBUG_SERIAL.println("failed to connect and hit timeout");
        }

        //save the custom parameters to FS
        if (shouldSaveConfig) {
                DEBUG_SERIAL.println("saving config");
                DynamicJsonBuffer jsonBuffer;
                JsonObject &json = jsonBuffer.createObject();
                json["device_id"] = custom_device_id.getValue();
                json["blynk_server"] = custom_blynk_server.getValue();
                json["blynk_token"] = custom_blynk_token.getValue();

                File configFile = SPIFFS.open("/config.json", "w");
                if (!configFile) {
                        DEBUG_SERIAL.println("failed to open config file for writing");
                }

                json.printTo(DEBUG_SERIAL);
                json.printTo(configFile);
                configFile.close();
                //end save
        }

        //if you get here you have connected to the WiFi
        DEBUG_SERIAL.println("WiFi connected");

        DEBUG_SERIAL.print("IP address: ");
        DEBUG_SERIAL.println(WiFi.localIP());
}

// Virtual pin update FW
BLYNK_WRITE(V22) {
        if (param.asInt() == 1) {
                DEBUG_SERIAL.println("Got a FW update request");

                char full_version[34] {""};
                strcat(full_version, device_id);
                strcat(full_version, "::");
                strcat(full_version, fw_ver);

                t_httpUpdate_return ret = ESPhttpUpdate.update("http://romfrom.space/get", full_version);
                switch (ret) {
                case HTTP_UPDATE_FAILED:
                        DEBUG_SERIAL.println("[update] Update failed.");
                        break;
                case HTTP_UPDATE_NO_UPDATES:
                        DEBUG_SERIAL.println("[update] Update no Update.");
                        break;
                case HTTP_UPDATE_OK:
                        DEBUG_SERIAL.println("[update] Update ok.");
                        break;
                }

        }
}

// Virtual pin reset settings
BLYNK_WRITE(V23) {
        factoryReset();
}

void setup() {
        // Init serial ports
        DEBUG_SERIAL.begin(115200);

        SENSOR_SERIAL.begin(9600);
        SENSOR_SERIAL.swap();  // GPIO15 (TX) and GPIO13 (RX)

        // Init I2C interface
        Wire.begin(I2C_SDA, I2C_SCL);

        // Init display
        u8g2.begin();
        drawBoot();

        // Init Humidity/Temperature sensor
        si7021.begin(I2C_SDA, I2C_SCL);

        // Init Pressure/Temperature sensor
        if (!bme.begin()) {
                DEBUG_SERIAL.println("Could not find a valid BMP085 sensor, check wiring!");
        }

        // Init filesystem
        if (!SPIFFS.begin()) {
                DEBUG_SERIAL.println("Failed to mount file system");
                ESP.reset();
        }

        // Setup WiFi
        setupWiFi();

        // Load config
        drawBoot();
        if (!loadConfig()) {
                DEBUG_SERIAL.println("Failed to load config");
                factoryReset();
        } else {
                DEBUG_SERIAL.println("Config loaded");
        }

        // Start blynk
        Blynk.config(blynk_token, blynk_server, blynk_port);

        // Setup a function to be called every 10 second
        timer.setInterval(10000L, sendMeasurements);

        sendMeasurements();
}

void loop() {
        Blynk.run();
        timer.run();
        draw();
}

Разработка сильно упростилась благодаря наличию хороших примеров и наличию функциональных библиотек:



Для работы с CO2 датчиком был использован чутка улучшенный пример из datasheet-а.


Что можно сделать лучше?


Здесь есть еще над чем поработать:
1) Решить проблему избыточного тепла в корусе
2) Сделать его еще компактнее — разведя плату и избавившись от проводов
3) Сделать работу в offline режиме


Что еще можно сделать? Какие у вас идеи? Если кто-то соберется сделать что-то подобное буду рад помочь и ответить на вопросы.


Существующие статьи на тему на Geektimes:


  1. Измеряем концентрацию CO2 в квартире с помощью MH-Z19
  2. Обзор инфракрасного датчика CO2 MH-Z19
  3. Wi-Fi измеритель CO2 на ESP8266 + K-30
Поделиться с друзьями
-->

Комментарии (119)


  1. xruyn
    31.01.2017 13:13

    Весьма забавно. Возможно ли использовать другие дачтики CO2? А то больно дорого 20уе отдавать.


    1. kumekay
      31.01.2017 13:15
      +7

      Датчик, конечно можно другой, но этот самый дешевый из доступных на рынке. Традиционно более дешевые электро-химические датчики стоят сравнимые деньги, при этом требуют сильно больше энергии (т.к. рабочая температура ~300С), обладают меньшей точностью и избирательностью (реагируют на другие газы)


    1. Rumlin
      31.01.2017 13:49
      +2

      Это еще дешево. Готовые устройства с такими датчиками еще дороже

      Цена постоянно обсуждается в комментариях к таким статьям. Например
      https://geektimes.ru/company/dadget/blog/253084/#comment_8436346

      Ну я и написал — «хорошие датчики стоят 70+ баксов».


  1. APLe
    31.01.2017 13:32
    +1

    gy-21 SI7021 i2c

    Ух ты, отдельное спасибо за упоминание! Не знал, что такие бывают.


  1. SL_RU
    31.01.2017 13:42
    +2

    Это не лучший экран для постоянной индикации — он выцветает чрезвычайно быстро — буквально за год-два потеряет 50% яркости.


    1. kumekay
      31.01.2017 15:00
      +1

      Спасибо, не знал что проблема у подобных OLED экранов стоит так остро.


      1. SL_RU
        31.01.2017 15:02
        +1

        Просто сам столкнулся с этой проблемой. Обожаю эти экранчики — слишком уж они милые, но эх…


        1. Dioxin
          01.02.2017 08:44
          +1

          Есть у меня старый мобильник — филипс ксениум с внешним экраном как раз таки ОЛЕД.
          Последнее время стоял все время на зарядке как будильник, в этом режиме экран постоянно горел.
          ЗА примерно 3 года выцвел в ноль.


        1. Salavat
          03.02.2017 07:44

          А если подключить HC-SR501 (датчик движения) и включать экранчик когда есть движение рядом? Давно об этом думал… Мой OLED пока едет с китая.


          1. ntfs1984
            03.02.2017 11:13
            +1

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

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


    1. GreyBear
      05.02.2017 08:44

      выцветает от наработки или от внешнего воздействия?


  1. AVI
    31.01.2017 13:50
    +2

    Как раз нахожусь в процессе конструирования/подбора компонентов для устройства с почти таким же функционалом.
    Единственное что хочу у себя добавить — это небольшой литиевый аккумулятор, который будет заряжаться при питании от USB. Так появится еще и автономность.
    Вместо bmp280+gy-21 планирую попробовать BME280, он измеряет давление, температуру и влажность сам в одном флаконе. Или может по нему есть какие-то нарекания?
    Ну, и поглядываю на Wemos D1 mini, можно еще места сэкономить…


    1. APLe
      31.01.2017 14:01

      небольшой литиевый аккумулятор
      Датчики углекислого газа потребляют достаточно большую мощность. И прогреваются при этом несколько минут, импульсами включать не получится.
      Так что придётся или аккумулятор делать уровня 18650, или хватать будет на несколько часов работы.


      1. Mad__Max
        08.02.2017 03:44

        ИК датчики СО2 (в примере как раз один из таких) потребляют немного — типовой уровень 10-30 мА. И на рабочий режим выходят за 20-30 секунд


        1. APLe
          08.02.2017 03:50

          По даташиту, MH-Z19 должна 5 минут прогреваться, ЕМНИП. А 10-30 мА – это достаточно много, пальчиковые батарейки будут садиться примерно за неделю, BL-4 («аккумулятор от Нокии») – дня за три.


          1. Mad__Max
            08.02.2017 05:06

            По даташиту у него 3 минуты. Но это как понимаю это для выхода на паспортную точность.

            Те пару ИК датчиков что мне попадались начинали выдавать показания уже через 20-30 секунд и более-менее адекватные показания, а не случайные значения от балды. Проверить эталона нет, но по крайней мере показания не сильно менялись после выжидания нескольких дополнительных минут. В пределах 5-15% и тут сложно сказать сколько из этого плавающая точность датчика, а сколько реальные изменения концентрации в воздухе от моего собственного присутствия и движения воздуха в помещении.

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


    1. kumekay
      31.01.2017 15:36
      +1

      Да, bme280 хорош, его планировал использовать. Но единственный доступный мне экземпляр оказался бракованным. Я обновил статью указав эту возможность.

      Питание от аккумулятора возможно, но тогда стоит использовать другой дисплей, вводить esp8266 в спящий режим, и подключаться к WiFi периодически.
      а вот сэкономить на питании mh-z19 сложнее. Его лучше держать включенным постоянно. Он потребляет ток около 18ma, а значит система с аккумулятором на 700ma, как у маленькой нокии, сможет продержаться 1,5 суток.


      1. AVI
        01.02.2017 16:34

        Под автономностью я имел в виду не пожизненную работу в автономном режиме, а просто чуть большую мобильность. Чтобы можно было пройтись по разным помещения и посмотреть сколько надышали тут, сколько надышали там, нормально ли проветривается вот здесь.
        Чтобы не искать свободные usb в каждом помещении или не таскать какой-нибудь PowerBank. А просто достал, включил — работает. Естественно не вечно.
        Даже сутки работы для таких целей более чем достаточно, можно и неплохую динамику заснять, если потребуется.


    1. apple01
      01.02.2017 19:56

      Пример реализации с использованием Wemos D1 mini и стандартного корпуса для Arduino
      <img src="" alt=«image»/>


  1. Vinney_pooh
    31.01.2017 13:52
    +3

    Почему не bme280? В нем 3 в одном — влажность, температура, давление.


    1. kumekay
      31.01.2017 13:54
      +4

      Да, bme280 хороший вариант, изначально планировал использовать именно его, но с aliexpress приехал неработающий экземпляр, поэтому использовал то, что было. А когда писал статью забыл про существование bme280. Спасибо за напоминание!


      1. Baton34
        01.02.2017 10:57
        +2

        Есть два bme280, показания влажности отличаются на 4 единицы, при том что давление и температура совпадает. Смотрел raw-данные они отличаются, но и поправочные коэффициенты разные.


        1. alexpp
          03.02.2017 11:12

          Аналогичная проблема — есть несколько датчиков, dht-22/bme-280/sht-21 — все показывают значения близкие, но не одинаковые. Даже в рамках одного датчика из разных партий.
          Увы, нет одинаковых, купленных пачкой — чтобы сравнить их показания, все покупались поштучно.
          Интересно было бы увидеть статистику по разбросу, точности и т.п. по самым популярным датчикам.


  1. ivaneska
    31.01.2017 14:18
    +1

    Дополнительно можно установить microSD слот и писать накарту все показания с привязкой по времени. Это позволит работать в оффлайне, при необходимости брать карту памяти с файлом и кидать её содержимое в комп, ну и вообще с картой памяти всё становится лучше как и с Bluetooth Wifi


    1. Ermito
      31.01.2017 14:30
      +1

      Собирал на arduino pro micro этот же датчик + датчик температуры + microsd, ethernet, RTC ии… скажем для дисплея доступных 29кб прошивки уже не хватает


      1. Alexander_Kharin
        01.02.2017 08:04

        я когда осваивал этот OLED дисплей и библиотеку для него для Ethernet-сервачка на Уно — тоже поначалу приуныл. Потом обнаружил, что необязательно тащить весь набор символов в память и, вообще, объём занимаемой памяти сильно зависит от размера шрифта. Мож вам тоже хватило бы памяти при использовании шрифта небольшого размера и только цифровых символов? :)


        1. Ermito
          01.02.2017 08:38

          Дело в том, что сейчас без дисплея занято 99% от доступной памяти. А «убирать ненужное» из библиотек для работы с сетью/sd-картой не очень хочется.


  1. artko
    31.01.2017 14:42
    +3

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

    картинка
    image


    1. electroneman
      31.01.2017 15:44

      И я тоже! image


      1. KonstantinSoloviov
        31.01.2017 20:17

        Там не спросил — сдержался, спрошу здесь
        ssid и ip-шник-то зачем??? :)

        Можете сколько угодно хаить едакий девайс, но

        светотофорный дизайн
        /


        1. electroneman
          01.02.2017 09:25

          ssid для того чтобы видеть куда станция пытается подключиться (или уже подключена). При отсутствии подключения там пишется имя временной точки доступа для изменения настроек сети. Кстати имя сети выбрано мной неслучайно. Это чтобы не палиться на работе))))
          ip-шник (он внутренний за роутером c DHCP) для того чтобы можно было зайти на внутренний веб-сервер esp8266 и посмотреть показания датчиков.
          Это первый вариант устройства. Главные на мой взгляд недостатки это питание от usb. Надо переходить на батареи, монохромный дисплей и использование спящего режима.
          Веб сервер оказался никому не нужен. Самые удобные «показометры» это экранчик и отправка данных куда-нить на сервер по get(php) или mqtt (чтобы народ мог посмотреть с телефона например).
          P.S. Для программирования использовал среду arduino


      1. Sonatix
        01.02.2017 16:43

        А что за дисплей был использован и как «присобачили»? :)


        1. electroneman
          02.02.2017 07:26

          Дисплей самый дешевый на чипе ili9341 с али.

          картинка страшный вид сзади
          image


    1. Dioxin
      01.02.2017 08:50

      Прелесть какая


  1. Alter_Ego
    31.01.2017 14:47

    А про датчики CO и мелких частиц в воздухе не думали? Вроде такого https://www.sparkfun.com/products/9689. Они, правда, крупные по размеру.


    1. kumekay
      31.01.2017 14:58
      +2

      Можно подключить без проблем. В моих условиях надобности в них нет, квартира без газа, поэтому СО опасаться не стоит, район без промышленности, поэтому пыли опасаться тоже не стоит.
      Хотя мой друг, живущий в Шанхае, активно использует подобную систему с датчиком пыли.


    1. ksv811212
      01.02.2017 00:03

      Игрался с датчиком пыли GP2Y1010AU0F, к сожалению не удалось получить сколько ни будь правдоподобные показания. и в инете на тот момент не много было описаний успешного опыта использования.


    1. dim133
      01.02.2017 12:22
      +2

      Подключил в свою поделку датчик пыли GP2Y1010AU0F.
      Достаточно точный. Реагирует на пайку, открытие корпуса компа, уборку в комнате.
      Как калибровать только непонятно.
      image


      1. edgi
        01.02.2017 15:38

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


        1. saege5b
          04.02.2017 00:05
          +1

          Как вариант осадить пыль паром.
          Удобно в ванной комнате.


  1. singerps
    31.01.2017 15:00

    Извиняюсь, а что и с чем соединять где-нибудь описано? Так сказать аппаратная часть, или вопрос на самом деле ламерский и на самом деле «и так всё ясно, не перепутаешь?»


    1. kumekay
      31.01.2017 15:01

      Нет, вопрос хороший. Я нарисую схему и обновлю пост вечером


      1. singerps
        01.02.2017 08:46

        спасибо! жду с нетерпением.


        1. kumekay
          02.02.2017 06:06

          Добавил раздел подключение


  1. 3cky
    31.01.2017 15:00

    Интересует, насколько стабильно работает устройство? Случаются ли зависания?


    1. kumekay
      31.01.2017 15:04

      Зависания случались только в режиме точки доступа. В рабочем режиме не наблюдал. Есть подозрения, что были спонтанные перезагрузки, но специально я это не отслеживал. Для бытового устройства работает весьма стабильно.


  1. norlin
    31.01.2017 15:06

    А кто-нибудь может посоветовать аналогичный готовый девайс?
    Можно даже без экранчика, главное чтоб по сети данные можно было смотреть, без облаков и прочих удалённых сервисов (либо они должны быть опциональны).


    1. mr_klimenko
      01.02.2017 02:10

      Вот готовое решение.
      http://mybroadlink.ru/catalog/meteostanciya-e-air/
      на али стоит 2400р.
      Только вместо CO2 показывает «качество воздуха» а это может быть что угодно.


      1. Brim
        01.02.2017 13:05

        Эта штука CO2 не меряет.


    1. Brim
      01.02.2017 13:08

      https://masterkit.ru/shop/others/dadget/2122569

      у китайцев цены примерно такие же и выше.


      1. norlin
        01.02.2017 13:15

        Она же USBшная, а не сетевая. Плюс требует дополнительный софт для работы.


        1. Brim
          01.02.2017 18:59

          И кто Вам мешает использовать любой БП с USB-разъемом?
          Софт использовать можно, но совсем не обязательно, все данные выводятся на экран.


          1. norlin
            01.02.2017 21:02

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


    1. Dylos1010
      03.02.2017 16:35

      Вот мне этот чувак сделал — http://forum.ixbt.com/topic.cgi?id=47:11005:1720#1720 — как раз то, что вам нужно, только там датчиков больше (но, наверно, он может сделать и только со2)


  1. gregst
    31.01.2017 15:08

    Можно заказать уже готовый и настроенный?

    Сколько будет стоить?


    1. kumekay
      01.02.2017 12:27

      Не думаю, что буду доводить это устройство до мелкой серии
      но что если делать, то нужно сделать печатную плату, чтобы упростить монтаж и сделать еще чуть компактнее.
      Да и качество 3д-печатного корпуса не дотягивает до ожиданий от купленного устройства.


    1. Dylos1010
      03.02.2017 20:36

      Выше отписал, я взял у этого парня — http://forum.ixbt.com/topic.cgi?id=47:11005:1720#1720 — работает норм.


  1. alexpp
    31.01.2017 15:14
    +1

    Чтобы избавиться от внутреннего тепла — мне пришлось вынести датчик за пределы корпуса. Неэстетично, зато правдиво — температура упала сразу на 2 градуса.


    1. BurlakovSG
      31.01.2017 16:34
      +1

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


      1. softmart
        03.02.2017 13:21

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


  1. KonstantinSoloviov
    31.01.2017 15:31
    +1

    Спасибо! Как раз собирался сотворить подобное именно в таком сочетании комплектующих и софта. Возьму Ваш девайс за основу :)

    Если же wifi сеть не обнаружится, то монитор загрузится в режиме ожидания настройки и поднимет точку доступа.
    Имхо, кнопка предпочтительнее тем более, что кнопка для прошивки все равно нужна:
    зажатая кнопка + включение питания — переход в режим прошивки
    включение питания + надпись на экране на пару секунд «Press button to enter setup» + нажимаем кнопку — переход в режим конфигурирования

    PlatformIO
    Уже можно пользоваться? Когда пробовал был очень сырой продукт, но явно амбициозный :)

    Корпус
    3D печать это здорово и модно, но все ж таки несколько аляповато получилось.

    но провода внутри все равно занимают большую часть места
    С учетом коннекторов — чудо, что вообще влезло )

    Ну, то все мелкие придирки, за исходники отдельное спасибо!


    1. xruyn
      31.01.2017 15:36

      PlatformIO лично мне очень нравится. В связке с Atom. Бывает, правда, плагин Atom Beatify подглючивает (сижу на Linux).


    1. kumekay
      31.01.2017 15:41

      PlatformIO можно пользоваться, работает весьма стабильно и активно поддерживается и разрабатывается.
      Кнопка, по моему мнению, не нужна.
      Всего одна строчка в коде `wifiManager.setTimeout(180);` позволяет не входить в режим настройки навечно — если проблема с сетью временная.
      Прошивка по воздуху активируется через мобильное приложение, для прошивки через провод, кнопка тоже не нужна.


      1. KonstantinSoloviov
        31.01.2017 16:07

        Ну, я в этом плане параноик :) Щелкнул пакетником в щетке, прошил по воздуху и вот уже в вашей домашней сети устройство которое делает то что нужно мне…


        1. kumekay
          31.01.2017 17:55
          +1

          Тут дырки в безопасности нет. Чтобы подключиться к устройству в режиме настройки, нужно знать пароль доступа к точке, который отображается на экране. Полагаю, что лестичной клети экрана не видно.
          Обновление по воздуху работает по другой схеме. URL с которого нужно загрузить новую прошивку содержится в текущей прошивке, а не передается по воздуху. По воздуху отправляется лишь команда «проверить обновления прошивки»
          К слову здесь используется простой http, но проблем с https (в том числе с tls 1.2) быть не должно


          1. KonstantinSoloviov
            31.01.2017 20:49
            +1

            Неплохой ответ, но

            Внутренний параноик:
            — это еще надо посмотреть как генерятся эти логин и пароль.

            Внутренний параноик (про TLS):
            — да, кстати, не припомню об реальном использовании ssl на девайсах с esp8266

            Внутренний параноик (вообще):
            — знать бы еще что эти китайцы в реализацию ip-стека засунули…

            :)


            1. kumekay
              31.01.2017 20:55
              +2

              — логин и пароль это серийники чипа и flash-a
              — ssl работает
              — Китайца зовут Иван https://github.com/esp8266/Arduino/issues/2537


      1. Shrizt
        03.02.2017 13:21

        Можно про прошивку подробнее? Какая технология обновления прошивки?
        Можно ссылкой…


        1. kumekay
          03.02.2017 13:23

          Это описано в документации к esp8266/arduino на английском


  1. poglazoff
    31.01.2017 18:36

    А как вы справляетесь с тем, что и MH-Z19, и OLED экран в общем-то существенно нагревают воздух внутри корпуса, искажая показания термодатчика?


    1. kumekay
      31.01.2017 18:42
      +1

      Нагревает в основном esp866 и dc-dc преобразователь, но я никак с этим не справляюсь


      1. poglazoff
        31.01.2017 19:05

        А пробовали измерить вносимую погрешность?


        1. kumekay
          31.01.2017 19:36

          3-4 градуса цельсия, она примерно постоянна и достигается через 15 минут работы устройства, наверное можно внести программную коррекцию.


          1. AllegroMod
            01.02.2017 07:37

            Осталось убедиться, что она константна (что 99% не так)


            1. kumekay
              01.02.2017 10:17

              Она, конечно, не константа. Но проградуировать, думаю, можно


        1. Fenogik
          01.02.2017 14:09
          +1

          Она не постоянна.
          Собрано два девайса 1. Макетка (датчики немного разнесены) — ESP8266 + MH-Z19 + SHT10 + BMP280. 2. «Готовое изделие» ESP8266 + MH-Z19 + DHT22 (датчик температуры вынесен на корпус).
          При «стоячем воздухе» разница в показаниях до 3'C, при проветривании (с учетом что стол стоит в углу) снижается до 1'C.
          Нагрев от понижаюки и самого еспешки довольна существенный.


  1. ntfs1984
    31.01.2017 21:57

    Лучшее, что здесь можно улучшить — отказаться от вороха коробочек в доме (подозреваю что цель этого проекта реальная, а не proof of concept).

    Пусть ваши датчики шлют данные в RAW на сервер (возможно даже по WiFi), а уже сервер их парсит. Вы сможете использовать эти данные для электромеханических устройств (PPM опустилось -> включился кулер вентиляции), вы сможете использовать их вдали от дома, вы сможете их просматривать со смартфона, вы сможете повесить себе рядом с входной дверью планшет или RPI-шку с TFT, и смотреть эти показания не отходя от кассы. Вы даже сможете находить закономерность между временем суток, освещению вашего окна солнцем, и падением уровня O2, или даже между PPM и вашей сонливостью.


    1. kumekay
      31.01.2017 21:59

      данные и шлются на сервер в сыром виде, более того сервер позволяет легко настроить web hook-и для каких-то дополнительных действий.


  1. wormball
    31.01.2017 22:42
    +2

    Я тут тоже MH-Z19 приобрёл и выяснил кое-какие недокументированные возможности. Для поста маловато, так что продублирую свой камент в другом посте:

    упомянутый MH-Z19 может ещё и температуру говорить, хотя в даташите это не указано. Однако указано, что градусник там есть, что и побудило меня порыться в интернете на эту тему.

    https://revspace.nl/MHZ19#Command_0x86_.28read_concentration.29

    Байт сразу после СО2 — температура плюс некоторая константа (по-хорошему надо её калибровать). Хотя здесь ложка дёгтя — для генерации дальнего ИК используется лампочка Ильича, каковая дополнительно нагревает датчик. Но это опять же мерять надо, насколько она его греет.

    Следующий байт — судя по всему, символизирует точность, достигаемую прибором на настоящий момент. А оная точность время от времени ухудшается — когда датчик тревожат, открывают дверь, либо вовсе без видимых причин (быть может, калибруется?), и тогда на графике мы видим пляски святого Витта. Коли всё хорошо — то байт равен 64, а когда плохо — то падает до 4. Например, это может пригодиться, ежели мы чем-то управляем на основании измерения СО2 — коли мы видим, что байт упал ниже 64, мы не рвёмся сразу переключать реле, а ждём, пока снова не станет 64, и показаниям снова можно будет доверять (ну или просто усредняем усерднее).

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

    Конец цитаты.

    Вот график: https://hsto.org/files/80c/0d2/20e/80c0d220e601462391b20c35ac9a7f13.png

    Когда температура падает (приблизительно до 8 градусов) — это я окно открыл.

    Собственно, видно, что когда показания СО2 колбасит, красная линия уходит вниз. И видно, что датчик довольно нежный — малейший ветерок — и показания скачут (быть может, это мой экземпляр такой?).

    А также видно, что чуть раньше 24 часов она внезапно волевым решением приравнивает концентрацию СО2 к 400 ппм. Говорят, что она таким образом автоматически калибруется — видит минимальную концентрацию за сутки и считает, что это 400 ппм. Лично на мой взгляд это довольно подлое поведение — калиброваться без спроса, к тому же тогда, когда нет никакой уверенности, что перед тобой эталон. Вполне может быть, что окна вовсе за сутки не будут открываться, да и с открытыми окнами нет гарантии, что у нас именно 400 — быть может, мы в Москве или, чего доброго, в Шанхае? Про график Килинга я и вовсе не говорю — надо очень долго ждать, чтобы изменение глобальной концентрации СО2 превысило заявленную погрешность прибора.


    1. SegreyBorovkov
      01.02.2017 04:20
      +3

      У меня ощущение, что он калибруется несколько хитрее. Я тоже замечал эти скачки раз в сутки. Но у меня после месяца непрерывной работы скачки показаний раз в сутки сильно уменьшились.

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

      Реально этот датчик подходит для примерной оценки, не более.


      1. wormball
        04.02.2017 00:56
        +1

        У меня, похоже, он докалибровался. Раньше, когда я заходил в комнату и закрывал дверь/окно, показания росли приблизительно на 800 ппм в час. А сейчас — чуть более 200. И подозрительно много времени проводит около 400 — это даже не объяснить тем, что минимальный уровень за 400 принимает. Похоже на то, он «хочет» намерять меньше 400 (а то и вовсе меньше нуля), но какие-то «моральные принципы» ему мешают.

        Этот случай как нельзя лучше раскрывает всё паскудство «интеллектуальной» автоматической калибровки. Выдавай он «сырые» значения — можно было бы самому вытаскивать из ни концентрацию (или хотя бы понять, сошёл датчик с ума или нет). Быть может, оные значения выдаются какой-либо командой из тех, что не проверены в упомянутой статье.

        Правда, в описанном происшествии есть некоторая доля моей «вины». Вначале я подсоединил датчик к +5 вольтам ардуины (а её к УСБ через трёхметровый удлинитель). Так она двое суток поработала. А потом подсоединил к +3,3 вольтам той же ардуины, а они там берутся из крена на 160 мА. И, видимо, этих мА ему не хватает, что выражается в визуально более долгом времени горения лампочки внутре и повышению температуры на 2 — 3 градуса. Тем не менее даже при таком раскладе он выдавал значения от 400 и до чуть более 2000, правда, норовя выдать 400 либо 1755. А ещё через сутки я подключил оный датчик к аккумулятору, чтобы ему точно тока хватило. И вот здесь-то и произошло описанное событие, как в том анекдоте про японский станок и суровых русских мужиков. Тем не менее вины с датчика это не снимает — коли ты такой умный, то мог бы догадаться, что не надо калиброваться, коли тебе питания не хватает. Или по крайней мере не распространять эту калибровку на тот случай, когда питания хватает.

        И похоже, что я таки понял, что символизирует неведомое число в конце вывода датчика. А символизирует оно время работы лампочки (ну или энергию, затраченную на оную работу). При питании от 5 вольт было чуть более 10 тысяч, а от крена на 3,3 В — уже более 15 тысяч (то бишь больше, чем при старте датчика). А от аккумулятора — сейчас рисует 9676.

        Теперь следующий шаг — надо вогнать ему в питание 1 ом и записывать график напряжения на таковом. И посмотреть корреляцию с неведомой величиной. А затем потестировать различные недокументированные команды — быть может, какой-то из них можно управлять зажиганием/измерением непосредственно.

        > Но у меня после месяца непрерывной работы скачки показаний раз в сутки сильно уменьшились.

        А после перезагрузки сохраняется калибровка или слетает?


        1. SegreyBorovkov
          04.02.2017 05:51

          У меня показание CO2 считывается посредством прошивки с wifi-iot и льется в zabbix.
          На графике видны почти ежедневные ступеньки на 50-100 ppm, около 11 утра
          image

          По графику хорошо можно оценить насколько точная у датчика на данный момент калибровка 400ppm — ведь по идее падение к 400 должно быть плавным, если в комнате не открыто окно, а открыто в другом месте.Плюс у меня датчик стоит в почти закрытой коробке, таким образом убираются случайные пики.
          Так вот падение к 400 иногда прямо очень плавное, а иногда — совсем нет.

          Сегодня находился в комнате 10кв. метров, с датчиком 2.5 часа. Дверь закрыта. Показание выросло линейно с 500 до 1500ppm. После открытия двери за две минуты упало до 900ppm, дальше еще за 12 минут — 700ppm. Выглядит адекватно.

          А вот на день раньше днем — полка 400ppm при том, что в комнате был человек (это видно по графику датчика движения) и в соседней комнате было чуть приоткрыто окно (это видно по температуре, гг). Мне кажется это странным.

          Похоже, что перезагрузка датчика не изменила калибровку. Скачков на 200-300 ppm нет.

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


    1. Fenogik
      01.02.2017 14:20

      Сверял эту выдаваемую температуру — десятки не выдает, целые совпадают.
      Датчики стояли на макетке.


  1. Jeditobe
    31.01.2017 23:31
    -4

    Кстати, на Алиэкспресе можно получать кэшбек до 10% процентов с почти мгновенным выводом. Пишите в личку, расскажу как.


  1. Bobnecat
    01.02.2017 07:35
    +2

    Не думал что тема еще актуальна так как в свое время собирал схожий девайс о котором я хотел написать еще год назад, но все никак не нашел свободного времени. Принцип работы немного отличается от того что собрал автор. У моей метеостанции на месте мозгов стоит Atmega328, а ESP8266 играет роль модема. Так-же имеется "протокол" для подключения беспроводных мини-модулей к которым можно понацеплять кучу датчиков, и все это добро отправлять на сайт народмониторинга. На данный момент из сенсоров стоят счетчик гейгера, СО2 (MH-Z19), BME280х2 и фоторезистор. В планах было присобачить датчики влажности почвы для напоминаний о поливе растений, но не свершилось, так как у меня больше нет растений в доме :) беспроводные модули кстати запитаны от CR2032. К чему про все это — если кто работает над схожим проектом или просто имеются вопросы, то можете мне написать. Постараюсь помочь чем смогу, так как думаю до написания статьи уже наверняка дело не дойдет.


    image


    1. kumekay
      01.02.2017 10:23

      А можно посмотреть на код работы с nrf24l01? на обеих сторонах?


      1. Bobnecat
        02.02.2017 04:25

        "Протокол" — это было громко сказано, поэтому и обернул это слово в кавычки. На самом деле все до безобразия просто. Используются нативные библиотеки <nRF24L01.h> и <RF24.h> а данные перед отсылкой пакуются в одну строчку разделенную запятыми, где первый параметр это ID датчика а все остальные параметры это собственно показания разных датчиков. Т.е когда "базовая станция" получает данные с удаленного датчика, первым делом она их распаковывает и сверяет ID, после чего уже точно знает какого рода данные полученные, сколько параметров и как их правильно разбить. Ко всему этому я добавил low power команды, чтобы после отправки данных, удаленный датчик засыпал и переводил NRF в энергосберегающий режим до следующего просыпания по истечению n-ного количества времени. Соответственно, как вы уже наверное догадались, все коммуникации работают в одностороннем порядке. Пишу развернутый ответ так как одновременно хотел ответить пользователю slgeo .


        Код относящийся именно к передаче и получению данных выглядят так (заранее извиняюсь за английский в комментариях — мне так было проще):


        Передатчик

        в setup:
        radio.begin(); //radio.setPayloadSize(8); //reduce payload to 8 (32 max) radio.setDataRate(RF24_250KBPS); //Pay attention to transfer speed radio.setRetries(15, 15); radio.openWritingPipe(rxAddr); radio.stopListening();


        в loop:
        radio.powerUp();`
        sprintf(msg, "%d,%d,%d,%d,%d,%d", sensorID, temp1002, hum1002, pres1002, lux1002, bat1002);


        radio.write( &msg, sizeof(msg)); //Send data to 'Receiver'
        radio.powerDown();
        `


    1. Rumlin
      01.02.2017 11:48

      офф а где Гейгер установлен? Есть в мыслях поставить у входной двери чтобы контролировать самое грязное — дорожную пыль.


      1. Bobnecat
        02.02.2017 04:35

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


        1. Rumlin
          02.02.2017 12:14

          Тоже так думал до прочтения книги

          Виноградов Ю.А. Ионизирующая радиация обнаружение, контроль, защита

          Вероятность куда то вступить выше, вероятности найти это же на высоте Н-цатого этажа.


    1. slgeo
      01.02.2017 12:25

      А протокол на основе MySensors или собственный?


      1. Bobnecat
        02.02.2017 04:36

        Ответил в предыдущем комментарии про передачу данных.


    1. alexpp
      03.02.2017 11:35

      Как долго живут датчики с автономным питанием? Можете привести схему беспроводного датчика — там используется nRF24L01 и Atmega328, правильно я понял?


      1. Bobnecat
        03.02.2017 18:33

        Все правильно Аtmega328 + nRF24L01 + BME280 + фоторезистор + светодиод. Так же стоят пару электролитических конденсаторов на линиях питания. Схемы к сожалению не составлял, но там все предельно просто. CR2032 по моим подсчетам должно хватить на более года работы (в идеальных условиях) если передавать данные каждые 10 минут или 250 дней если передавать данные каждые 5 минут. Дальнобойность проверял в пределах 10 метров через стены — все работало. В спящем режиме такой набор потребляет порядка 6-7 микроампер (если верить дешевому китайскому мультиметру). Самая главная фишка, это подобрать адекватный модуль nRF24L01+ и правильно его настроить, так как даже из одной партии разные модули имеют разный ток потребления. По паспорту, там должно быть что-то около 2 микроампер. + 4 микроампер потребляет Atmega328 в глубоком сне. На данный момент беспроводной датчик уже проработал 4 месяца без замены батареи.


  1. alexpp
    01.02.2017 10:12
    +1

    Добавьте в статью, пожалуйста, схему устройства.


    1. kumekay
      02.02.2017 06:06
      +1

      Добавил раздел подключение


  1. marsdenden
    01.02.2017 16:46

    Как-то оборвано предложение

    Cперва оно попытается подключиться к сохраненной ранее сети и успешно выполнив


    1. kumekay
      01.02.2017 16:46

      Спасибо, поправил. В следующий раз лучше в личку.


      1. marsdenden
        01.02.2017 16:48
        -2

        Да я тут пока нубик )))


  1. alexzzam
    01.02.2017 17:57
    +1

    Круто, запишу идеи. А я всё никак не соберусь доделать похожую штуку, но на своей плате и с AVR. И с MQ-135 для углекислого газа.


  1. HzXiO
    02.02.2017 00:08

    Добрый день! А можно ли сделать удалённый мониторинг. С мобилы видеть параметры и управлять чем нибудь, если на стороне контроллера будет WIFI c GSM модемом со статическим ай пи?


    1. kumekay
      02.02.2017 00:33

      Можно, но без Blynk. С blynk тоже можно, но с промежуточным сервером. В этом случае и статичный IP не нужен.


    1. SegreyBorovkov
      02.02.2017 02:49

      Посмотрите https://wifi-iot.com, там очень широкий функционал, код писать не нужно.
      Если на роутере есть рут, можно попробовать телеграм-бот поднять и без белого ip, но для этого вероятно надо будет писать код.


    1. Bobnecat
      02.02.2017 04:38

      Можете посмотреть в сторону narodmon но не знаю как у них с удаленным управлением.


  1. iCoderXXI
    02.02.2017 00:48

    А CO эта штука может измерять?


    1. kumekay
      02.02.2017 01:32

      Эта нет, для CO есть недорогой (~$1.3) датчик MQ-7. Он имеет массу недостатков, но задачу решать должен. Он был упомянут в статье на гиктаймс


      1. iCoderXXI
        02.02.2017 01:35

        Благодрю! CO намертво связывает гемоглобин до его утилизации в селезенке, это может произойти и через 2-3 месяца. Так-что если что и мониторить в первую очередь, так это СО. Т.е. человек может иметь высокий гемоглобин, и, при этом, страдать от гипоксии, причем ущерб получают все органы и системы при недостатке кислорода идут сложные цепные реакции, некоторые потом весьма труднообратимые.


        1. kumekay
          02.02.2017 02:00
          +1

          Да, но СО имеет смысл мониторить только там, где может быть его повышенная концентрация, в гаражах, в квартирах — если есть газовый водогрей или газовая плита. В отсутствии возможных продуктов горения, смысла в мониторинге особо нет. СО2 же есть везде, и при высоких концентрациях продуктивность и комфорт может сильно падать


          1. iCoderXXI
            02.02.2017 02:06

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


            1. kumekay
              02.02.2017 02:21

              При курении — да. При дыхании нет. В душных офисах — нет, в них как раз стоит контролировать содержание CO2, которое легко может превысить 2000 ppm.


              1. iCoderXXI
                02.02.2017 03:23

                В организм окись углерода поступает через органы дыхания. Моноксид углерода способен соединяться с гемоглобином в 200 раз быстрее, чем кислород с образованием карбоксигемоглобина (HbCO). Период его полураспада — 4-6 часов. Расщепление карбоксигемоглобина на гемоглобин (Hb) и монооксид углерода (CO) происходит в 10 000 раз медленнее, чем расщепление оксигемоглобина на Hb и O2. Поэтому при наличии во вдыхаемом воздухе CO кислород постепенно вытесняется из гемоглобина. Уже при концентрации 0,1% CO в воздухе больше половины гемоглобина крови превращается в карбоксигемоглобин; в результате нарушается перенос кислорода от лёгких к тканям и развивается так называемое угарное отравление. Карбоксигемоглобин не способен переносить кислород к тканям организма, поэтому при отравлении окисью углерода у человека может быстро наступить смерть. Хроническая экспозиция низких концентраций СО может привести к возникновению таких симптомов, как головная боль, усталость, головокружение, ощущение биения сердца, боли в груди, тошнота, рвота и абдоминальные боли.



                Результаты исследования уровня монооксида углерода в выдыхаемом воздухе.

                Исследование взрослых не курящих лиц показало, что концентрация СО у них определялась в интервале от 0 до 1 ррm. У эпизодически курящих лиц в возрасте от 25 до 62 лет концентрация монооксида углерода определялась от 0 до 3 ррm. У лиц, выкуривающих более 10 сигарет в день концентрация СО определялась от 16 до 21 ррm.

                Так, у лиц, выкуривающих в день более 12 сигарет в день, по сравнению с теми, кто выкуривал до 5 сигарет в день, наблюдалось резкое повышение уровня СО. Связано это, по-видимому, с тем, что в организме курильщика накапливается монооксид углерода в бронхолегочной системе, который не успевает вывестись, поскольку при интенсивном курении (более 10 сигарет в день) курильщик, как правило, курит каждые 1-2 часа в день, а период полураспада карбоксигемоглобина составляет 4-6 часов, что и обусловливает высокое содержание СО в организме.



                Так как концентрация угарного газа в бронхах и легких повышается при длительных поездках на велосипеде по автострадах, нахождении в задымленном помещение, при чрезмерном вдыхании выхлопных газов и т. п.



                Источник: http://www.hintfox.com/article/soderzhanie-ygarnogo-gaza-v-vidihaemom-vozdyhe-kak-indikator-tabakokyrenija-podrostkov.html

                В общем не совсем понятна эта история, но я так думаю что если в душном офисе соберутся активные курильщики, а это не редкость, то накочегарят они там что мама не горюй…


                1. iCoderXXI
                  02.02.2017 03:31

                  Ну и вот до кучи, не знаю насколько достоверно, но задуматься заставит http://zdravclub.ru/news/162-prebyvanie-v-neprovetrivaemom-pomeshhenii.html


  1. Millano
    02.02.2017 01:33

    Есть ещё вроде модуль mg-811 пример (https://ru.aliexpress.com/cp/mg811-co2-sensor-online-shopping.html) его можно использовать!?


    1. kumekay
      02.02.2017 01:35

      Можно, но mg-811 менее точный, с худшей избирательностью, большим энергопотреблением и дороже.


  1. doom369
    03.02.2017 16:39

    По вебке — любую бесплатную вебку можно подлючить через вебхуки в Blynk. На локальном сервере можно даже убрать лимит в 1 вебхук в секунду на 1 пин (если надо чаще).


    1. kumekay
      03.02.2017 16:43

      А что такое "вебка" в данном контексте?


      1. doom369
        03.02.2017 16:49
        +1

        Веб интерфейс.


      1. doom369
        03.02.2017 16:51

        При чем работает в обе стороны. Можно слать из блинка в вебку и можно из вебки слдать в блинк (в апку и в железо)


  1. scolonel
    03.02.2017 21:26
    +1

    Спасибо за публикацию. «Заразно» это все наверное, вот прототип подобной конструкции. В качестве анализатора воздуха мечтаю использовать MQ-135.
    image