Меняем структуру FS для хранения модулей и добавляем скрипт сборки модулей для интеграции в меню и библиотеки

This commit is contained in:
2022-03-07 11:56:09 +03:00
parent d9e111470a
commit c453a98685
54 changed files with 964 additions and 308 deletions

View File

@@ -0,0 +1,95 @@
/******************************************************************
Used Adafruit ADS1X15 Driver (16-bit Differential or Single-Ended ADCs with PGA and Comparator)
Support for ADS1015/1115
https://github.com/adafruit/Adafruit_ADS1X15
adapted for version 4 @Serghei63
******************************************************************/
#include "Global.h"
#include "classes/IoTItem.h"
#include "Wire.h"
#include <Adafruit_ADS1X15.h> // Библиотека для работы с модулями ADS1115 и ADS1015
Adafruit_ADS1115 ads;
class Ads1115 : public IoTItem {
int _pin;
bool _isRaw;
bool _isInited = false;
public:
Ads1115(String parameters): IoTItem(parameters) {
String tmp;
jsonRead(parameters, "pin", tmp);
_pin = tmp.toInt();
jsonRead(parameters, "mode", tmp);
_isRaw = tmp == "raw";
if (!ads.begin()) {
Serial.println("Failed to initialize ADS.");
_isInited = false;
} else _isInited = true;
String gain;
jsonRead(parameters, "gain", gain);
if (gain == "1x") ads.setGain(GAIN_ONE);
else if (gain == "2x") ads.setGain(GAIN_TWO);
else if (gain == "4x") ads.setGain(GAIN_FOUR);
else if (gain == "8x") ads.setGain(GAIN_EIGHT);
else if (gain == "16x") ads.setGain(GAIN_SIXTEEN);
else ads.setGain(GAIN_TWOTHIRDS);
// ВОЗМОЖНЫЕ ВАРИАНТЫ УСТАНОВКИ КУ:
// ads.setGain(GAIN_TWOTHIRDS); //| 2/3х | +/-6.144V | 1bit = 0.1875mV |
// ads.setGain(GAIN_ONE); //| 1х | +/-4.096V | 1bit = 0.125mV |
// ads.setGain(GAIN_TWO); //| 2х | +/-2.048V | 1bit = 0.0625mV |
// ads.setGain(GAIN_FOUR); //| 4х | +/-1.024V | 1bit = 0.03125mV |
// ads.setGain(GAIN_EIGHT); //| 8х | +/-0.512V | 1bit = 0.015625mV |
// ads.setGain(GAIN_SIXTEEN); //| 16х | +/-0.256V | 1bit = 0.0078125mV |
}
void doByInterval() {
if (_isInited) {
if (_isRaw) value.valD = ads.readADC_SingleEnded(_pin); // Чтение АЦП нулевого канала(rawdata)
else value.valD = ads.computeVolts(ads.readADC_SingleEnded(_pin)); // Чтение АЦП нулевого канала (Вольты)
regEvent(value.valD, "ADC1115");
}
}
~Ads1115() {};
};
void *getAPI_Ads1115(String subtype, String param)
{
if (subtype == F("Ads1115")) {
return new Ads1115(param);
} else {
return nullptr;
}
}
// {
// "name": "26. Датчик напряжения ADS1115",
// "num": 26,
// "type": "Reading",
// "subtype": "Ads1115",
// "id": "Ads3",
// "widget": "anydataVlt",
// "page": "Сенсоры",
// "descr": "ADS_3",
// "pin": "0",
// "mode": "volt",
// "gain": "3/4x",
// "plus": 0,
// "multiply": 1,
// "round": 100,
// "int": 10
// }

View File

@@ -0,0 +1,21 @@
[
{
"name": "Датчик напряжения ADS1115",
"num": 28,
"type": "Reading",
"subtype": "Ads1115",
"id": "Ads3",
"widget": "anydataVlt",
"page": "Сенсоры",
"descr": "ADS_3",
"pin": "0",
"mode": "volt",
"gain": "3/4x",
"plus": 0,
"multiply": 1,
"round": 100,
"int": 10
}
]

View File

@@ -0,0 +1,7 @@
[env:esp8266_4mb]
lib_deps =
adafruit/Adafruit ADS1X15 @ ^2.3.0
[env:esp32_4mb]
lib_deps =
adafruit/Adafruit ADS1X15 @ ^2.3.0

View File

@@ -0,0 +1,60 @@
/******************************************************************
Used Adafruit AHT20 Driver (temperature and humidity sensor)
Support for AHT20
https://github.com/adafruit/Adafruit_AHTX0
adapted for version 4 @Serghei63
******************************************************************/
#include "Global.h"
#include "classes/IoTItem.h"
#include "Adafruit_AHTX0.h"
#include <map>
Adafruit_AHTX0 aht;
sensors_event_t temp, humidity;
class Aht20t : public IoTItem {
public:
Aht20t(String parameters): IoTItem(parameters) { }
void doByInterval() {
value.valD = temp.temperature;
if (value.valD != -200) regEvent(value.valD, "Aht20t"); // TODO: найти способ понимания ошибки получения данных
else SerialPrint("E", "Sensor AHTt", "Error");
}
~Aht20t() {};
};
class Aht20h : public IoTItem {
public:
Aht20h(String parameters): IoTItem(parameters) { }
void doByInterval() {
value.valD = humidity.relative_humidity;
if (value.valD != -200) regEvent(value.valD, "Aht20h"); // TODO: найти способ понимания ошибки получения данных
else SerialPrint("E", "Sensor AHTt", "Error");
}
~Aht20h() {};
};
void* getAPI_Aht20(String subtype, String param) {
if (subtype == F("Aht20t")) {
aht.begin();
aht.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
return new Aht20t(param);
} else if (subtype == F("Aht20h")) {
aht.begin();
aht.getEvent(&humidity, &temp);// populate temp and humidity objects with fresh data
return new Aht20h(param);
} else {
return nullptr;
}
}

View File

@@ -0,0 +1,27 @@
[{
"name": "Cенсор температуры AHT20",
"num": 12,
"type": "Reading",
"subtype": "Aht20t",
"id": "Temp20",
"widget": "anydataTmp",
"page": "Сенсоры",
"descr": "AHT20 Температура",
"int": 15,
"addr": "0x38",
"round": 1
},
{
"name": "Cенсор влажности AHT20",
"num": 13,
"type": "Reading",
"subtype": "Aht20h",
"id": "Hum20",
"widget": "anydataHum",
"page": "Сенсоры",
"descr": "AHT20 Влажность",
"int": 15,
"addr": "0x38",
"round": 1
}
]

View File

@@ -0,0 +1,7 @@
[env:esp8266_4mb]
lib_deps =
Adafruit AHTX0
[env:esp32_4mb]
lib_deps =
Adafruit AHTX0

View File

@@ -0,0 +1,55 @@
#include "Global.h"
#include "classes/IoTItem.h"
extern IoTGpio IoTgpio;
//Это файл сенсора, в нем осуществляется чтение сенсора.
//для добавления сенсора вам нужно скопировать этот файл и заменить в нем текст AnalogAdc на название вашего сенсора
//Название должно быть уникальным, коротким и отражать суть сенсора.
class AnalogAdc : public IoTItem {
private:
//=======================================================================================================
// Секция переменных.
//Это секция где Вы можете объявлять переменные и объекты arduino библиотек, что бы
//впоследствии использовать их в loop и setup
unsigned int _pin;
public:
//=======================================================================================================
// setup()
//это аналог setup из arduino. Здесь вы можете выполнять методы инициализации сенсора.
//Такие как ...begin и подставлять в них параметры полученные из web интерфейса.
//Все параметры хранятся в перемененной parameters, вы можете прочитать любой параметр используя jsonRead функции:
// jsonReadStr, jsonReadBool, jsonReadInt
AnalogAdc(String parameters): IoTItem(parameters) {
_pin = jsonReadInt(parameters, "pin");
}
//=======================================================================================================
// doByInterval()
//это аналог loop из arduino, но вызываемый каждые int секунд, заданные в настройках. Здесь вы должны выполнить чтение вашего сенсора
//а затем выполнить regEvent - это регистрация произошедшего события чтения
//здесь так же доступны все переменные из секции переменных, и полученные в setup
//если у сенсора несколько величин то делайте несколько regEvent
//не используйте delay - помните, что данный loop общий для всех модулей. Если у вас планируется длительная операция, постарайтесь разбить ее на порции
//и выполнить за несколько тактов
void doByInterval() {
value.valD = IoTgpio.analogRead(_pin);
regEvent(value.valD, "AnalogAdc"); //обязательный вызов хотяб один
}
//=======================================================================================================
~AnalogAdc() {};
};
//после замены названия сенсора, на функцию можно не обращать внимания
//если сенсор предполагает использование общего объекта библиотеки для нескольких экземпляров сенсора, то в данной функции необходимо предусмотреть
//создание и контроль соответствующих глобальных переменных
void* getAPI_AnalogAdc(String subtype, String param) {
if (subtype == F("AnalogAdc")) {
return new AnalogAdc(param);
} else {
return nullptr;
}
}

View File

@@ -0,0 +1,18 @@
[
{
"name": "Аналоговый сенсор",
"num": 1,
"type": "Reading",
"subtype": "AnalogAdc",
"id": "t",
"widget": "anydataTmp",
"page": "Сенсоры",
"descr": "Температура",
"map": "1,1024,1,100",
"plus": 0,
"multiply": 1,
"round": 1,
"pin": 0,
"int": 15
}
]

View File

@@ -0,0 +1,97 @@
/******************************************************************
Used Adafruit BME280 Driver (Barometric Pressure Sensor)
Support for BME280
https://github.com/adafruit/Adafruit_BME280_Library
******************************************************************/
#include "Global.h"
#include "classes/IoTItem.h"
#include <Adafruit_BME280.h>
#include <map>
std::map<String, Adafruit_BME280*> bmes;
class Bme280t : public IoTItem {
private:
Adafruit_BME280* _bme;
public:
Bme280t(Adafruit_BME280* bme, String parameters) : IoTItem(parameters) {
_bme = bme;
}
void doByInterval() {
value.valD = _bme->readTemperature();
if (value.valD < 145)
regEvent(value.valD, "Bme280t");
else
SerialPrint("E", "Sensor Bme280t", "Error");
}
~Bme280t() {};
};
class Bme280h : public IoTItem {
private:
Adafruit_BME280* _bme;
public:
Bme280h(Adafruit_BME280* bme, String parameters) : IoTItem(parameters) {
_bme = bme;
}
void doByInterval() {
value.valD = _bme->readHumidity();
if (value.valD < 100)
regEvent(value.valD, "Bme280h");
else
SerialPrint("E", "Sensor Bme280h", "Error");
}
~Bme280h() {};
};
class Bme280p : public IoTItem {
private:
Adafruit_BME280* _bme;
public:
Bme280p(Adafruit_BME280* bme, String parameters) : IoTItem(parameters) {
_bme = bme;
}
void doByInterval() {
value.valD = _bme->readPressure();
if (value.valD > 0) {
value.valD = value.valD / 1.333224 / 100;
regEvent(value.valD, "Bme280p");
} else
SerialPrint("E", "Sensor Bme280p", "Error");
}
~Bme280p() {};
};
void* getAPI_Bme280(String subtype, String param) {
if (subtype == F("Bme280t") || subtype == F("Bme280h") || subtype == F("Bme280p")) {
String addr;
jsonRead(param, "addr", addr);
if (bmes.find(addr) == bmes.end()) {
bmes[addr] = new Adafruit_BME280();
bmes[addr]->begin(hexStringToUint8(addr));
}
if (subtype == F("Bme280t")) {
return new Bme280t(bmes[addr], param);
} else if (subtype == F("Bme280h")) {
return new Bme280h(bmes[addr], param);
} else if (subtype == F("Bme280p")) {
return new Bme280p(bmes[addr], param);
}
} else {
return nullptr;
}
}

View File

@@ -0,0 +1,41 @@
[
{
"name": "Cенсор температуры Bme280",
"num": 9,
"type": "Reading",
"subtype": "Bme280t",
"id": "tmp3",
"widget": "anydataTmp",
"page": "Сенсоры",
"descr": "Температура",
"int": 15,
"addr": "0x77",
"round": 1
},
{
"name": "Cенсор давления Bme280",
"num": 10,
"type": "Reading",
"subtype": "Bme280p",
"id": "Press3",
"widget": "anydataMm",
"page": "Сенсоры",
"descr": "Давление",
"int": 15,
"addr": "0x77",
"round": 1
},
{
"name": "Cенсор влажности Bme280",
"num": 11,
"type": "Reading",
"subtype": "Bme280h",
"id": "Hum3",
"widget": "anydataHum",
"page": "Сенсоры",
"descr": "Влажность",
"int": 15,
"addr": "0x77",
"round": 1
}
]

View File

@@ -0,0 +1,8 @@
[env:esp8266_4mb]
lib_deps =
adafruit/Adafruit BME280 Library
[env:esp32_4mb]
lib_deps =
adafruit/Adafruit BME280 Library

View File

@@ -0,0 +1,75 @@
/******************************************************************
Used Adafruit BMP280 Driver (Barometric Pressure Sensor)
Support for BMP280
https://github.com/adafruit/Adafruit_BMP280_Library
******************************************************************/
#include "Global.h"
#include "classes/IoTItem.h"
#include <Adafruit_BMP280.h>
#include <map>
std::map<String, Adafruit_BMP280*> bmps;
class Bmp280t : public IoTItem {
private:
Adafruit_BMP280* _bmp;
public:
Bmp280t(Adafruit_BMP280* bmp, String parameters): IoTItem(parameters) {
_bmp = bmp;
}
void doByInterval() {
value.valD = _bmp->readTemperature();
if (String(value.valD) != "nan") regEvent(value.valD, "Bmp280t");
else SerialPrint("E", "Sensor DHTt", "Error");
}
~Bmp280t() {};
};
class Bmp280p : public IoTItem {
private:
Adafruit_BMP280* _bmp;
public:
Bmp280p(Adafruit_BMP280* bmp, String parameters): IoTItem(parameters) {
_bmp = bmp;
}
void doByInterval() {
value.valD = _bmp->readPressure();
if (String(value.valD) != "nan") {
value.valD = value.valD / 1.333224 / 100;
regEvent(value.valD, "Bmp280p");
} else SerialPrint("E", "Sensor DHTh", "Error");
}
~Bmp280p() {};
};
void* getAPI_Bmp280(String subtype, String param) {
if (subtype == F("Bmp280t") || subtype == F("Bmp280p")) {
String addr;
jsonRead(param, "addr", addr);
if (bmps.find(addr) == bmps.end()) {
bmps[addr] = new Adafruit_BMP280();
bmps[addr]->begin(hexStringToUint8(addr));
}
if (subtype == F("Bmp280t")) {
return new Bmp280t(bmps[addr], param);
} else if (subtype == F("Bmp280p")) {
return new Bmp280p(bmps[addr], param);
}
} else {
return nullptr;
}
}

View File

@@ -0,0 +1,28 @@
[
{
"name": "Cенсор температуры Bmp280",
"num": 7,
"type": "Reading",
"subtype": "Bmp280t",
"id": "tmp3",
"widget": "anydataTmp",
"page": "Сенсоры",
"descr": "280 Температура",
"int": 15,
"addr": "0x77",
"round": 1
},
{
"name": "Cенсор давления Bmp280",
"num": 8,
"type": "Reading",
"subtype": "Bmp280p",
"id": "Press3",
"widget": "anydataMm",
"page": "Сенсоры",
"descr": "280 Давление",
"int": 15,
"addr": "0x77",
"round": 1
}
]

View File

@@ -0,0 +1,8 @@
[env:esp8266_4mb]
lib_deps =
adafruit/Adafruit BMP280 Library
[env:esp32_4mb]
lib_deps =
adafruit/Adafruit BMP280 Library

View File

@@ -0,0 +1,80 @@
/******************************************************************
Used DHT Temperature & Humidity Sensor library for Arduino & ESP32.
Support for DHT11 and DHT22/AM2302/RHT03
https://github.com/beegee-tokyo/arduino-DHTesp
******************************************************************/
#include "Global.h"
#include "classes/IoTItem.h"
#include "DHTesp.h"
#include <map>
std::map<int, DHTesp*> dhts;
class Dht1122t : public IoTItem {
private:
DHTesp* _dht;
public:
Dht1122t(DHTesp* dht, String parameters): IoTItem(parameters) {
_dht = dht;
}
void doByInterval() {
value.valD = _dht->getTemperature();
if (String(value.valD) != "nan") regEvent(value.valD, "Dht1122t");
else SerialPrint("E", "Sensor DHTt", "Error");
}
~Dht1122t() {};
};
class Dht1122h : public IoTItem {
private:
DHTesp* _dht;
public:
Dht1122h(DHTesp* dht, String parameters): IoTItem(parameters) {
_dht = dht;
}
void doByInterval() {
value.valD = _dht->getHumidity();
if (String(value.valD) != "nan") regEvent(value.valD, "Dht1122h");
else SerialPrint("E", "Sensor DHTh", "Error");
}
~Dht1122h() {};
};
void* getAPI_Dht1122(String subtype, String param) {
if (subtype == F("Dht1122t") || subtype == F("Dht1122h")) {
int pin;
String senstype;
jsonRead(param, "pin", pin);
jsonRead(param, "senstype", senstype);
if (dhts.find(pin) == dhts.end()) {
dhts[pin] = new DHTesp();
if (senstype == "dht11") {
dhts[pin]->setup(pin, DHTesp::DHT11);
} else if (senstype == "dht22") {
dhts[pin]->setup(pin, DHTesp::DHT22);
}
}
if (subtype == F("Dht1122t")) {
return new Dht1122t(dhts[pin], param);
} else if (subtype == F("Dht1122h")) {
return new Dht1122h(dhts[pin], param);
}
} else {
return nullptr;
}
}

View File

@@ -0,0 +1,28 @@
[
{
"name": "Cенсор температуры dht11",
"num": 5,
"type": "Reading",
"subtype": "Dht1122t",
"id": "tmp3",
"widget": "anydataTmp",
"page": "Сенсоры",
"descr": "Температура",
"int": 15,
"pin": 0,
"senstype": "dht11"
},
{
"name": "Cенсор влажности dht11",
"num": 6,
"type": "Reading",
"subtype": "Dht1122h",
"id": "Hum3",
"widget": "anydataHum",
"page": "Сенсоры",
"descr": "Влажность",
"int": 15,
"pin": 0,
"senstype": "dht11"
}
]

View File

@@ -0,0 +1,7 @@
[env:esp8266_4mb]
lib_deps =
beegee-tokyo/DHT sensor library for ESPx
[env:esp32_4mb]
lib_deps =
beegee-tokyo/DHT sensor library for ESPx

View File

@@ -0,0 +1,96 @@
#include "Global.h"
#include "classes/IoTItem.h"
#include "DallasTemperature.h"
#include <OneWire.h>
#include <map>
//глобальные списки необходимы для хранения объектов об активных линиях 1-wire используемых разными датчиками из модуля. Ключ - номер пина
std::map<int, OneWire*> oneWireTemperatureArray;
std::map<int, DallasTemperature*> sensorsTemperatureArray;
class Ds18b20 : public IoTItem {
private:
//для работы библиотеки с несколькими линиями необходимо обеспечить каждый экземпляр класса ссылками на объекты настроенные на эти линии
OneWire* oneWire;
DallasTemperature* sensors;
//описание параметров передаваемых из настроек датчика из веба
String _addr;
int _pin;
int _index;
public:
//=======================================================================================================
// setup()
//это аналог setup из arduino. Здесь вы можете выполнять методы инициализации сенсора.
//Такие как ...begin и подставлять в них параметры полученные из web интерфейса.
//Все параметры хранятся в перемененной parameters, вы можете прочитать любой параметр используя jsonRead функции:
// jsonReadStr, jsonReadBool, jsonReadInt
Ds18b20(String parameters) : IoTItem(parameters) {
jsonRead(parameters, "pin", _pin);
jsonRead(parameters, "index", _index, false);
jsonRead(parameters, "addr", _addr, false);
//учитываем, что библиотека может работать с несколькими линиями на разных пинах, поэтому инициируем библиотеку, если линия ранее не использовалась
if (oneWireTemperatureArray.find(_pin) == oneWireTemperatureArray.end()) {
oneWire = new OneWire((uint8_t)_pin);
sensors = new DallasTemperature();
sensors->setOneWire(oneWire);
sensors->begin();
sensors->setResolution(12);
oneWireTemperatureArray[_pin] = oneWire;
sensorsTemperatureArray[_pin] = sensors;
} else {
oneWire = oneWireTemperatureArray[_pin];
sensors = sensorsTemperatureArray[_pin];
}
}
//=======================================================================================================
// doByInterval()
//это аналог loop из arduino, но вызываемый каждые int секунд, заданные в настройках. Здесь вы должны выполнить чтение вашего сенсора
//а затем выполнить regEvent - это регистрация произошедшего события чтения
//здесь так же доступны все переменные из секции переменных, и полученные в setup
//если у сенсора несколько величин то делайте несколько regEvent
//не используйте delay - помните, что данный loop общий для всех модулей. Если у вас планируется длительная операция, постарайтесь разбить ее на порции
//и выполнить за несколько тактов
void doByInterval() {
//запускаем опрос измерений у всех датчиков на линии
sensors->requestTemperatures();
//Определяем адрес. Если парамтер addr не установлен, то узнаем адрес по индексу
// TODO: понять как лучше. в текущей реализации адрес вычисляется каждый раз при опросе шины, это хорошо при отладке,
// но при постоянном контакте и использовании правильнее генерировать адрес при инициализации модуля. Но тогда нужно перезагружать устройство при новом датчике
DeviceAddress deviceAddress;
if (_addr == "") {
sensors->getAddress(deviceAddress, _index);
} else {
string2hex(_addr.c_str(), deviceAddress);
}
//получаем температуру по адресу
value.valD = sensors->getTempC(deviceAddress);
char addrStr[20] = "";
hex2string(deviceAddress, 8, addrStr);
if (value.valD != -127)
regEvent(value.valD, "addr: " + String(addrStr)); //обязательный вызов для отправки результата работы
else
SerialPrint("E", "Sensor Ds18b20", "Error");
}
//=======================================================================================================
~Ds18b20() {};
};
//после замены названия сенсора, на функцию можно не обращать внимания
//если сенсор предполагает использование общего объекта библиотеки для нескольких экземпляров сенсора, то в данной функции необходимо предусмотреть
//создание и контроль соответствующих глобальных переменных
void* getAPI_Ds18b20(String subtype, String param) {
if (subtype == F("Ds18b20")) {
return new Ds18b20(param);
} else {
return nullptr;
}
}

View File

@@ -0,0 +1,17 @@
[
{
"name": "Cенсор температуры ds18b20",
"num": 2,
"type": "Reading",
"subtype": "Ds18b20",
"id": "dstmp",
"widget": "anydataTmp",
"page": "Сенсоры",
"descr": "DS Температура",
"int": 15,
"pin": 2,
"index": 0,
"addr": "",
"round": 1
}
]

View File

@@ -0,0 +1,8 @@
[env:esp8266_4mb]
lib_deps =
milesburton/DallasTemperature@^3.9.1
[env:esp32_4mb]
lib_deps =
milesburton/DallasTemperature@^3.9.1

View File

@@ -0,0 +1,59 @@
/******************************************************************
Used GY21 Driver (temperature and humidity sensor)
Support for HTY21 , SHT21 , Si7021
https://github.com/adafruit/Adafruit_AHTX0
adapted for version 4 Alecs Alecs
******************************************************************/
#include "Global.h"
#include "classes/IoTItem.h"
#include "Wire.h"
#include "GY21.h"
GY21* sensor = nullptr;
class GY21t : public IoTItem {
public:
GY21t(String parameters): IoTItem(parameters) { }
void doByInterval() {
//wire->read();
value.valD = sensor->GY21_Temperature();
if (value.valD < 300) regEvent(value.valD, "GY21"); // TODO: найти способ понимания ошибки получения данных
else SerialPrint("E", "Sensor GY21t", "Error");
}
~GY21t() {};
};
class GY21h : public IoTItem {
public:
GY21h(String parameters): IoTItem(parameters) { }
void doByInterval() {
//sht->read();
value.valD = sensor->GY21_Humidity();
if (value.valD != 0) regEvent(value.valD, "GY21h"); // TODO: найти способ понимания ошибки получения данных
else SerialPrint("E", "Sensor GY21h", "Error");
}
~GY21h() {};
};
void* getAPI_GY21(String subtype, String param) {
if (subtype == F("GY21t") || subtype == F("GY21h")) {
if (!sensor) {
sensor = new GY21;
if (sensor) Wire.begin(SDA, SCL);
}
if (subtype == F("GY21t")) {
return new GY21t(param);
} else if (subtype == F("GY21h")) {
return new GY21h(param);
}
} else {
return nullptr;
}
}

View File

@@ -0,0 +1,26 @@
[
{
"name": "Cенсор температуры GY21",
"num": 16,
"type": "Reading",
"subtype": "GY21t",
"id": "tmp4",
"widget": "anydataTmp",
"page": "Сенсоры",
"descr": "Температура",
"round": 1,
"int": 15
},
{
"name": "Cенсор влажности GY21",
"num": 17,
"type": "Reading",
"subtype": "GY21h",
"id": "Hum4",
"widget": "anydataHum",
"page": "Сенсоры",
"descr": "Влажность",
"round": 1,
"int": 15
}
]

View File

@@ -0,0 +1,8 @@
[env:esp8266_4mb]
lib_deps =
https://github.com/JonasGMorsch/GY-21.git
[env:esp32_4mb]
lib_deps =
https://github.com/JonasGMorsch/GY-21.git

View File

@@ -0,0 +1,54 @@
/******************************************************************
Used ClosedCube HDC1080 Driver (temperature and humidity sensor)
Support for HDC1080
https://github.com/closedcube/ClosedCube_HDC1080_Arduino
adapted for version 4 @Serghei63
******************************************************************/
#include "Global.h"
#include "classes/IoTItem.h"
#include "Wire.h"
#include "ClosedCube_HDC1080.h"
#include <map>
//создаем объект HDC1080
ClosedCube_HDC1080 hdc1080;
class Hdc1080t : public IoTItem {
public:
Hdc1080t(String parameters): IoTItem(parameters) { }
void doByInterval() {
value.valD = hdc1080.readTemperature();
if (value.valD < 124) regEvent(value.valD, "Hdc1080t");
else SerialPrint("E", "Sensor Hdc1080t", "Error");
}
~Hdc1080t() {};
};
class Hdc1080h : public IoTItem {
public:
Hdc1080h(String parameters): IoTItem(parameters) { }
void doByInterval() {
value.valD = hdc1080.readHumidity();
if (value.valD < 99 ) regEvent(value.valD, "Hdc1080h");
else SerialPrint("E", "Sensor Hdc1080h", "Error");
}
~Hdc1080h() {};
};
void* getAPI_Hdc1080(String subtype, String param) {
if (subtype == F("Hdc1080t")) {
hdc1080.begin(0x40);
return new Hdc1080t(param);
} else if (subtype == F("Hdc1080h")) {
hdc1080.begin(0x40);
return new Hdc1080h(param);
} else {
return nullptr;
}
}

View File

@@ -0,0 +1,28 @@
[
{
"name": "Cенсор температуры HDC1080",
"num": 14,
"type": "Reading",
"subtype": "Hdc1080t",
"id": "Temp1080",
"widget": "anydataTmp",
"page": "Сенсоры",
"descr": "1080 Температура",
"int": 15,
"addr": "0x40",
"round": 1
},
{
"name": "Cенсор влажности HDC1080",
"num": 15,
"type": "Reading",
"subtype": "Hdc1080h",
"id": "Hum1080",
"widget": "anydataHum",
"page": "Сенсоры",
"descr": "1080 Влажность",
"int": 15,
"addr": "0x40",
"round": 1
}
]

View File

@@ -0,0 +1,7 @@
[env:esp8266_4mb]
lib_deps =
ClosedCube HDC1080
[env:esp32_4mb]
lib_deps =
ClosedCube HDC1080

View File

@@ -0,0 +1,689 @@
/******************************************************************
Support for MHZ19
adapted for version 4 @cmche
******************************************************************/
#include "Global.h"
#include "classes/IoTItem.h"
#include <SoftwareSerial.h>
extern IoTGpio IoTgpio;
int rxPinCO2 = 14; // D5 // зеленый провод сенсора к D2 / 4
int txPinCO2 = 16; // D0 // синий провод сенсора к D1/5
SoftwareSerial swSerialCO2(rxPinCO2, txPinCO2); // RX, TX// ESP8266 D7 / D6 Blue/Green
int MHZ19_request(int request);
void MHZ19uart_init();
bool MHZ19uart_flag = true;
// int MHZ19C_PREHEATING_TIME = 2 * 60 * 1000;// покажет реальные данные после прогрева, через 2 мин.
int MHZ19C_PREHEATING_TIME = 2 * 30 * 1000; // покажет реальные данные после прогрева, через 2 мин.
//int prevTemperature = 0;
int temperature = 0;
bool temperatureUpdated = false;
int prevRange = 5000;
int range = 5000; // по умолнчанию стоит шкала 5000 (не 2000 как в мануале)
bool rangeChaged = false;
int prevABC = 1;
int ABC = 1;
bool ABCchanged = false;
//Это файл сенсора, в нем осуществляется чтение сенсора.
class Mhz19uart : public IoTItem
{
private:
//=======================================================================================================
// Секция переменных.
public:
//=======================================================================================================
Mhz19uart(String parameters) : IoTItem(parameters)
{
rxPinCO2 = jsonReadInt(parameters, "rxPin");
txPinCO2 = jsonReadInt(parameters, "txPin");
range = jsonReadInt(parameters, "range");
ABC = jsonReadInt(parameters, "ABC");
}
//=======================================================================================================
// doByInterval()
void doByInterval()
{
MHZ19uart_init();
if (millis() > MHZ19C_PREHEATING_TIME)
{
Serial.println("Start checkUARTCO2");
value.valD = MHZ19_request(1);
}
regEvent(value.valD, "Mhz19uart"); //обязательный вызов хотяб один
}
//=======================================================================================================
~Mhz19uart() {};
};
//после замены названия сенсора, на функцию можно не обращать внимания
//если сенсор предполагает использование общего объекта библиотеки для нескольких экземпляров сенсора, то в данной функции необходимо предусмотреть
//создание и контроль соответствующих глобальных переменных
class Mhz19pwm : public IoTItem
{
private:
//=======================================================================================================
// Секция переменных.
int pwmPin; ///// желтый провод сенсора к D8 (14-D5 ok)
public:
//=======================================================================================================
Mhz19pwm(String parameters) : IoTItem(parameters)
{
pwmPin = jsonReadInt(parameters, "pin");
}
//=======================================================================================================
void doByInterval()
{
MHZ19pwm_init();
if (millis() > MHZ19C_PREHEATING_TIME) //
{
Serial.println("Start checkPWM_CO2");
value.valD = MHZ19pwm_request();
}
regEvent(value.valD, "Mhz19pwm"); //обязательный вызов хотяб один
}
//=======================================================================================================
void MHZ19pwm_init()
{
static bool MHZ19pwm_flag = true;
if (MHZ19pwm_flag)
{
pinMode(pwmPin, INPUT);
MHZ19pwm_flag = false;
}
}
int MHZ19pwm_request()
{
int reply;
Serial.println("Запрос замера по PWM запущен");
unsigned long th, tl, ppm = 0, ppm2 = 0, ppm3 = 0;
do
{
th = pulseIn(pwmPin, HIGH, 1004000) / 1000;
tl = 1004 - th;
ppm2 = 2000 * (th - 2) / (th + tl - 4); // расчёт для диапазона от 0 до 2000ppm
ppm3 = 5000 * (th - 2) / (th + tl - 4); // расчёт для диапазона от 0 до 5000ppm
} while (th == 0);
// Serial.print(th);
// Serial.println(" <- Milliseconds PWM is HIGH");
if (range == 2000)
{
reply = ppm2;
Serial.print(ppm2);
Serial.println(" <- ppm2 (PWM) with 2000ppm as limit");
}
else
{
reply = ppm3;
Serial.print(ppm3);
Serial.println(" <- ppm3 (PWM) with 5000ppm as limit");
}
Serial.println("Completed checkPwmCO2");
return reply;
}
~Mhz19pwm() {};
};
//====================TEMP===================================================================================
class Mhz19temp : public IoTItem
{
private:
//=======================================================================================================
// Секция переменных.
public:
//====================TEMP===================================================================================
Mhz19temp(String parameters) : IoTItem(parameters)
{
rxPinCO2 = jsonReadInt(parameters, "rxPin");
txPinCO2 = jsonReadInt(parameters, "txPin");
range = jsonReadInt(parameters, "range");
ABC = jsonReadInt(parameters, "ABC");
}
//=======================================================================================================
void doByInterval()
{
// Serial.println("Start Mhz19temp doByInterval");
if (temperatureUpdated)
{
value.valD = temperature;
temperatureUpdated = false;
}
else
{
MHZ19uart_init();
Serial.println("Start temperature request");
if (MHZ19_request(13))
{
value.valD = temperature;
}; // change
}
regEvent(value.valD, "Mhz19temp"); //обязательный вызов хотяб один
}
//=======================================================================================================
//=======================================================================================================
~Mhz19temp() {};
};
//=======================Range================
class Mhz19range : public IoTItem
{
private:
public:
Mhz19range(String parameters) : IoTItem(parameters)
{
rxPinCO2 = jsonReadInt(parameters, "rxPin");
txPinCO2 = jsonReadInt(parameters, "txPin");
range = jsonReadInt(parameters, "range");
ABC = jsonReadInt(parameters, "ABC");
}
void doByInterval()
{
if (range != prevRange)
{
MHZ19uart_init();
Serial.println("Start change range");
if (range == 2000)
{
if (MHZ19_request(9))
{
prevRange = 2000;
value.valD = 2000;
} // change range to 2000
}
else
{
if (MHZ19_request(10))
{
prevRange = 5000;
value.valD = 5000;
} // change range to 5000
}
}
else
{
value.valD = prevRange;
}
regEvent(value.valD, "Mhz19range"); //обязательный вызов хотяб один
}
~Mhz19range() {};
};
//===================ABC=================
class Mhz19ABC : public IoTItem
{
private:
public:
Mhz19ABC(String parameters) : IoTItem(parameters)
{
rxPinCO2 = jsonReadInt(parameters, "rxPin");
txPinCO2 = jsonReadInt(parameters, "txPin");
range = jsonReadInt(parameters, "range");
ABC = jsonReadInt(parameters, "ABC");
}
void doByInterval()
{
if (ABC != prevABC)
{
if (ABC == 1)
{
if (MHZ19_request(7))
{
prevABC = 1;
value.valD = 1;
} // change ABC to 1
}
else
{
if (MHZ19_request(8))
{
prevABC = 0;
value.valD = 0;
} // change ABC to 0
}
}
else
{
value.valD = prevABC;
}
regEvent(value.valD, "Mhz19ABC"); //обязательный вызов хотяб один
}
~Mhz19ABC() {};
};
///============== end of classes==========================
void *getAPI_Mhz19(String subtype, String param)
{
if (subtype == F("Mhz19uart"))
{
return new Mhz19uart(param);
}
else if (subtype == F("Mhz19pwm"))
{
return new Mhz19pwm(param);
}
else if (subtype == F("Mhz19temp"))
{
return new Mhz19temp(param);
}
else if (subtype == F("Mhz19range"))
{
return new Mhz19range(param);
}
else if (subtype == F("Mhz19ABC"))
{
return new Mhz19ABC(param);
}
else
{
return nullptr;
}
}
void MHZ19uart_init()
{
if (MHZ19uart_flag)
{
int reply;
swSerialCO2.begin(9600);
delay(50);
reply = MHZ19_request(2); // show range, for test of uart only
Serial.print("show range reply = ");
Serial.println(reply);
if (reply)
{
MHZ19uart_flag = false;
}
}
if (!MHZ19uart_flag)
{
static int prevABC;
int reply;
if (ABC != prevABC)
{
if (ABC)
{
reply = MHZ19_request(7); // ABC on
}
else
{
reply = MHZ19_request(8); // ABC off
}
Serial.print("ABC change reply = ");
Serial.println(reply);
}
if (reply)
{
prevABC = ABC;
}
}
static bool MHZ19_range_flag = true;
if (MHZ19_range_flag && !MHZ19uart_flag && (millis() > 30 * 1000))
{
int reply;
if (range == 2000)
{
reply = MHZ19_request(9); // Установка шкалы 0-2000
// 255 155 0 0 7 208 0 3 139
}
else
{
reply = MHZ19_request(10); // Установка шкалы 0-5000
// 255 155 0 0 19 136 0 3 199
}
Serial.print("Scale change reply = ");
Serial.println(reply);
if (reply)
{
reply = MHZ19_request(2); // show range
Serial.print("show range reply = ");
Serial.println(reply);
MHZ19_range_flag = false;
}
}
}
int MHZ19_request(int request)
{
int reply;
Serial.print("prevRange = ");
Serial.println(prevRange);
byte uartReqSamplePpm[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79}; // PPM
// 255 1 134 0 0 0 0 0 121
// Response 255 134 1 148 67 0 0 0 162
byte uartReqSampleABCon[9] = {0xFF, 0x01, 0x79, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xE6}; // ABC logic on
// 255 1 121 160 0 0 0 0 230
//Response 255 121 1 0 0 0 0 0 134
byte uartReqSampleABCoff[9] = {0xFF, 0x01, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86}; // ABC logic off
byte uartReqSampleABCstatus[9] = {0xFF, 0x01, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82}; // ABC logic status
byte uartReqSample1000Range[9] = {0xFF, 0x01, 0x99, 0x00, 0x00, 0x00, 0x03, 0xE8, 0x7B};
byte uartReqSample2000Range[9] = {0xFF, 0x01, 0x99, 0x00, 0x00, 0x00, 0x07, 0xD0, 0x8F}; // задаёт диапазон 0 - 2000ppm
byte uartReqSample3000Range[9] = {0xFF, 0x01, 0x99, 0x00, 0x00, 0x00, 0x0B, 0xB8, 0xA3}; // задаёт диапазон 0 - 2000ppm
byte uartReqSample5000Range[9] = {0xFF, 0x01, 0x99, 0x00, 0x00, 0x00, 0x13, 0x88, 0xCB}; // задаёт диапазон 0 - 5000ppm
// 255 1 153 0 0 0 19 136 203
// Response 255 153 1 0 0 0 0 0 102
byte uartReqSampleRequestRange[9] = {0xFF, 0x01, 0x9B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64}; // запрос диапазона
// request // 255 1 155 0 0 0 0 0 100
//reply // 255 1 155 0 0 0 0 0 100
byte uartReqSampleZeroPnt[9] = {0xFF, 0x01, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78}; // !!ZERO POINT CALIBRATION
byte uartReqSampleReset[9] = {0xFF, 0x01, 0x8D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72}; // reset
byte uartReqSampleReset1[9] = {0xFF, 0x01, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87}; // reset - did not work out
byte request_cmd[9];
// byte c;
switch (request)
{
// случаи 3-7 для перезапуска сенсора
case 1:
{
Serial.println("Запрос No.1 - отправлен. Запрос замера по UART");
for (int i = 0; i < 9; i++)
{
request_cmd[i] = uartReqSamplePpm[i];
}
}
break;
case 2:
{
for (int i = 0; i < 9; i++)
{
request_cmd[i] = uartReqSampleRequestRange[i];
}
Serial.println("Запрос No.2 - отправлен. Запрос шкалы");
}
break;
case 3:
{
// код для запуска сенсора с работой по UART (запуск таймера)
Serial.println("Запрос No.3 - отправлен. Сенсор по UART запущен");
}
break;
case 4:
{
// код для остановке сенсора с работой по UART (остановка таймера)
Serial.println("Запрос No.4 - отправлен. Сенсор по UART остановлен");
}
break;
case 5:
{
// код для запуска сенсора с работой по PWM (запуск таймера)
Serial.println("Запрос No.5 - отправлен. Сенсор по PWM запущен");
}
break;
case 6:
{
// код для остановки сенсора с работой по PWM (остановка таймера)
Serial.println("Запрос No.6 - отправлен. Сенсор по PWM остановлен");
}
break;
case 7:
{
for (int i = 0; i < 9; i++)
{
request_cmd[i] = uartReqSampleABCon[i];
}
Serial.println("Запрос No.7 - отправлен. Включаем функцию атокалибровки");
}
break;
case 8:
{
for (int i = 0; i < 9; i++)
{
request_cmd[i] = uartReqSampleABCoff[i];
}
Serial.println("Запрос No.8 - отправлен. Выключаем функцию атокалибровки");
}
break;
case 9:
{
for (int i = 0; i < 9; i++)
{
request_cmd[i] = uartReqSample2000Range[i];
}
Serial.println("Запрос No.9 - отправлен. Установливаем шкалу 0-2000");
}
break;
case 10:
{
for (int i = 0; i < 9; i++)
{
request_cmd[i] = uartReqSample5000Range[i];
}
Serial.println("Запрос No.10 - отправлен. Установливаем шкалу 0-5000");
}
break;
case 11:
{
for (int i = 0; i < 9; i++)
{
request_cmd[i] = uartReqSampleZeroPnt[i];
}
Serial.println("Запрос No.11 - отправлен. Калибровка. Установливаем нулевой уровень");
}
break;
case 12:
{
for (int i = 0; i < 9; i++)
{
request_cmd[i] = uartReqSampleReset1[i];
}
Serial.println("Запрос No.11 - отправлен. Запрос на Сброс");
}
break;
case 13:
{
for (int i = 0; i < 9; i++)
{
request_cmd[i] = uartReqSamplePpm[i];
}
Serial.println("Запрос No.13 - отправлен. Запрос по Температуре");
}
break;
default:
// byte c = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
// if nothing else matches, do the default
// default is optional
break;
}
swSerialCO2.write(request_cmd, 9);
Serial.print("Request : ");
for (int i = 0; i < 9; i++)
{
Serial.print(" ");
Serial.print(request_cmd[i]);
}
Serial.println(" ");
delay(50);
unsigned char response[9];
Serial.print("Response :");
swSerialCO2.readBytes(response, 9);
for (int i = 0; i < 9; i++)
{
Serial.print(" ");
Serial.print(response[i]);
}
Serial.println(" ");
byte crc = 0;
for (int i = 1; i < 8; i++) crc += response[i];
crc = 255 - crc;
crc += 1;
if (!(response[0] == 0xFF && response[8] == crc))
{
Serial.println("Range CRC error: " + String(crc) + " / " + String(response[8]));
reply = 0;
}
else
{
// Serial.println("No CRC errors");
switch (request)
{
case 1:
{
unsigned int responseHigh = (unsigned int)response[2];
unsigned int responseLow = (unsigned int)response[3];
unsigned int ppm = (256*responseHigh) + responseLow;
Serial.print("CO2 UART = ");
Serial.println(ppm);
temperature = response[4] - 44; // - 40;
Serial.print("Temperature = ");
Serial.println(temperature);
temperatureUpdated = true;
reply = ppm;
}
break;
case 2:
{
reply = 1;
Serial.println("Case 2 - OK. На запрос шкалы пришел ответ");
}
break;
case 3:
{
// Serial.println("Case 3 - OK");
reply = 1;
}
break;
case 4:
{
// Serial.println("Case 4 - OK");
reply = 1;
}
break;
case 5:
{
// Serial.println("Case 5 - OK");
reply = 1;
}
break;
case 6:
{
Serial.println("Case 6 - OK");
reply = 1;
}
break;
case 7:
{
Serial.println("Case 7 - OK. ABC включен");
reply = 1;
}
break;
case 8:
{
Serial.println("Case 8 - OK. ABC выключен");
reply = 1;
}
break;
case 9:
{
Serial.println("Case 9 - OK. Установлена шкала 0-2000");
reply = 1;
prevRange = 2000;
}
break;
case 10:
{
Serial.println("Case 9 - OK. Установлена шкала 0-5000");
reply = 1;
prevRange = 5000;
}
break;
case 11:
{
reply = 1;
Serial.println("Запрос No.11 - сработал. Калибровка. Установлен нулевой уровень");
}
break;
case 12:
{
reply = 1;
Serial.println("Запрос No.12 - сработал. Сброс произошел");
}
break;
case 13:
{
reply = 1;
temperature = response[4] - 44; // - 40;
Serial.println("Запрос No.12 - сработал. Температура получена");
Serial.println(temperature);
}
break;
default:
// byte c = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79};
// if nothing else matches, do the default
// default is optional
break;
}
}
// Serial.print("reply = ");
// Serial.println(reply);
return reply;
}

View File

@@ -0,0 +1,86 @@
[
{
"name": "Датчик CO2 MHZ-19 UART",
"num": 20,
"type": "Reading",
"subtype": "Mhz19uart",
"id": "co2uart",
"widget": "anydataPpm",
"page": "Сенсоры",
"descr": "CO2uart",
"plus": 0,
"multiply": 1,
"round": 1,
"pin": 0,
"rxPin": 14,
"txPin": 16,
"int": 15,
"range": 5000,
"ABC": 1
},
{
"name": "Датчик CO2 MHZ-19 PWM",
"num": 21,
"type": "Reading",
"subtype": "Mhz19pwm",
"id": "co2pwm",
"widget": "anydataPpm",
"page": "Сенсоры",
"descr": "CO2pwm",
"plus": 0,
"multiply": 1,
"round": 1,
"pin": 16,
"int": 300
},
{
"name": "Cенсор температуры от MHZ-19 UART",
"num": 22,
"type": "Reading",
"subtype": "Mhz19temp",
"id": "Mhz19temp",
"widget": "anydataTmp",
"page": "Сенсоры",
"descr": "Температура",
"plus": 0,
"multiply": 1,
"round": 1,
"rxPin": 14,
"txPin": 16,
"ABC": 1,
"int": 30
},
{
"name": "Рабочий диапазон от MHZ-19 UART",
"num": 23,
"type": "Reading",
"subtype": "Mhz19range",
"id": "Mhz19range",
"widget": "anydataPpm",
"page": "Сенсоры",
"descr": "Диапазон",
"plus": 0,
"multiply": 1,
"round": 1,
"rxPin": 14,
"txPin": 16,
"range": 5000,
"ABC": 1,
"int": 30
},
{
"name": "Автокалибровка от MHZ-19 UART",
"num": 24,
"type": "Reading",
"subtype": "Mhz19ABC",
"id": "Mhz19ABC",
"widget": "anydataDef",
"page": "Сенсоры",
"descr": "ABC",
"rxPin": 14,
"txPin": 16,
"range": 5000,
"ABC": 1,
"int": 30
}
]

View File

@@ -0,0 +1,209 @@
/******************************************************************
Supports Sds011, implements whole Laser Dust Sensor Control Protocol V1.3,
should also work with other Sds sensors.
https://github.com/lewapek/sds-dust-sensors-arduino-library
adapted for version 4 @cmche
******************************************************************/
#include "Global.h"
#include "classes/IoTItem.h"
extern IoTGpio IoTgpio;
#include "SdsDustSensor.h"
int rxPinSDS = 13; // D7 подключаем к Tx сенсора
int txPinSDS = 12; // D6 подключаем к Rx сенсора
SdsDustSensor sds(rxPinSDS, txPinSDS);
unsigned int warmUp;
unsigned int period;
bool SDS011_init_flag = true;
void SDS011_init();
float Sds011request(int sensorID);
//Это файл сенсора, в нем осуществляется чтение сенсора.
//для добавления сенсора вам нужно скопировать этот файл и заменить в нем текст AnalogAdc на название вашего сенсора
//Название должно быть уникальным, коротким и отражать суть сенсора.
class Sds011_25 : public IoTItem
{
private:
//=======================================================================================================
// Секция переменных.
//Это секция где Вы можете объявлять переменные и объекты arduino библиотек, что бы
//впоследствии использовать их в loop и setup
// unsigned int _pin;
public:
//=======================================================================================================
// setup()
//это аналог setup из arduino. Здесь вы можете выполнять методы инициализации сенсора.
//Такие как ...begin и подставлять в них параметры полученные из web интерфейса.
//Все параметры хранятся в перемененной parameters, вы можете прочитать любой параметр используя jsonRead функции:
// jsonReadStr, jsonReadBool, jsonReadInt
Sds011_25(String parameters) : IoTItem(parameters)
{
// _pin = jsonReadInt(parameters, "pin");
rxPinSDS = jsonReadInt(parameters, "rxPin");
txPinSDS = jsonReadInt(parameters, "txPin");
warmUp = jsonReadInt(parameters, "warmUp"); // сек. пробужнение должен быть больше
period = jsonReadInt(parameters, "period"); // сек. время зарогрева/продувки, затем идут замеры
}
//=======================================================================================================
// doByInterval()
//это аналог loop из arduino, но вызываемый каждые int секунд, заданные в настройках. Здесь вы должны выполнить чтение вашего сенсора
//а затем выполнить regEvent - это регистрация произошедшего события чтения
//здесь так же доступны все переменные из секции переменных, и полученные в setup
//если у сенсора несколько величин то делайте несколько regEvent
//не используйте delay - помните, что данный loop общий для всех модулей. Если у вас планируется длительная операция, постарайтесь разбить ее на порции
//и выполнить за несколько тактов
void doByInterval()
{
SDS011_init();
Serial.println("request from 25");
value.valD = Sds011request(25);
regEvent(value.valD, "Sds011_25"); //обязательный вызов хотяб один
}
~Sds011_25() {};
};
//////////////////////////////////// for PM 10//=
class Sds011_10 : public IoTItem
{
private:
//=======================================================================================================
// Секция переменных.
//Это секция где Вы можете объявлять переменные и объекты arduino библиотек, что бы
//впоследствии использовать их в loop и setup
public:
//=======================================================================================================
// setup()
//это аналог setup из arduino. Здесь вы можете выполнять методы инициализации сенсора.
//Такие как ...begin и подставлять в них параметры полученные из web интерфейса.
//Все параметры хранятся в перемененной parameters, вы можете прочитать любой параметр используя jsonRead функции:
// jsonReadStr, jsonReadBool, jsonReadInt
Sds011_10(String parameters) : IoTItem(parameters)
{
// _pin = jsonReadInt(parameters, "pin");
rxPinSDS = jsonReadInt(parameters, "rxPin");
txPinSDS = jsonReadInt(parameters, "txPin");
warmUp = jsonReadInt(parameters, "warmUp"); // сек. пробужнение должен быть больше
period = jsonReadInt(parameters, "period"); // сек. время зарогрева/продувки, затем идут замеры
}
//=======================================================================================================
// doByInterval()
//это аналог loop из arduino, но вызываемый каждые int секунд, заданные в настройках. Здесь вы должны выполнить чтение вашего сенсора
//а затем выполнить regEvent - это регистрация произошедшего события чтения
//здесь так же доступны все переменные из секции переменных, и полученные в setup
//если у сенсора несколько величин то делайте несколько regEvent
//не используйте delay - помните, что данный loop общий для всех модулей. Если у вас планируется длительная операция, постарайтесь разбить ее на порции
//и выполнить за несколько тактов
void doByInterval()
{
SDS011_init();
Serial.println("request from 10");
value.valD = Sds011request(10);
regEvent(value.valD, "Sds011_10"); //обязательный вызов хотяб один
}
~Sds011_10() {};
};
//после замены названия сенсора, на функцию можно не обращать внимания
//если сенсор предполагает использование общего объекта библиотеки для нескольких экземпляров сенсора, то в данной функции необходимо предусмотреть
//создание и контроль соответствующих глобальных переменных
void *getAPI_Sds011(String subtype, String param)
{
if (subtype == F("Sds011_25"))
{
return new Sds011_25(param);
}
else if (subtype == F("Sds011_10"))
{
return new Sds011_10(param);
}
else
{
return nullptr;
}
}
float Sds011request(int sensorID)
{
float reply = 0;
static int a = 0;
static float pm25 = 0;
static float pm10 = 0;
static int startMillis = millis();
if (a == 0)
{
Serial.print("SDS011 ... warmUp = ");
Serial.print(warmUp);
Serial.print(" period = ");
Serial.println(period);
sds.wakeup();
startMillis = millis();
a = a + 1;
}
if (a == 1 && millis() >= (startMillis + warmUp * 1000))
{
PmResult pm = sds.readPm();
if (pm.isOk())
{
pm25 = pm.pm25;
pm10 = pm.pm10;
Serial.print("PM2.5 = ");
Serial.print(pm25);
Serial.print(" PM10 = ");
Serial.println(pm10);
a = a + 1;
sds.sleep();
}
else
{
Serial.print("Could not read values from sensor 25, reason: ");
Serial.println(pm.statusToString());
a = a + 1;
}
}
if (a > 1 && millis() >= (startMillis + period * 1000))
{
Serial.println("end of period for pm25");
a = 0;
}
if (sensorID == 25)
{
reply = pm25;
}
if (sensorID == 10)
{
reply = pm10;
}
return reply;
}
void SDS011_init()
{
if (SDS011_init_flag)
{
sds.begin();
Serial.println(sds.queryFirmwareVersion().toString()); // prints firmware version
// Serial.println(sds.setActiveReportingMode().toString()); //
String ReportingMode = sds.setActiveReportingMode().toString();
Serial.println(ReportingMode);
if (ReportingMode == "Mode: active")
{
SDS011_init_flag = false;
}
}
}

View File

@@ -0,0 +1,38 @@
[
{
"name": "Датчик пыли SDS011 PM25",
"num": 18,
"type": "Reading",
"subtype": "Sds011_25",
"id": "pmuart25",
"widget": "anydataPpm",
"page": "Сенсоры",
"descr": "PM-2.5",
"plus": 0,
"multiply": 1,
"round": 10,
"rxPin": 13,
"txPin": 12,
"int": 15,
"warmUp": 30,
"period": 300
},
{
"name": "Датчик пыли SDS011 PM10",
"num": 19,
"type": "Reading",
"subtype": "Sds011_10",
"id": "pmuart10",
"widget": "anydataPpm",
"page": "Сенсоры",
"descr": "PM-10",
"plus": 0,
"multiply": 1,
"round": 10,
"rxPin": 13,
"txPin": 12,
"int": 15,
"warmUp": 30,
"period": 300
}
]

View File

@@ -0,0 +1,7 @@
[env:esp8266_4mb]
lib_deps =
Nova Fitness Sds dust sensors library@1.5.1
[env:esp32_4mb]
lib_deps =
Nova Fitness Sds dust sensors library@1.5.1

View File

@@ -0,0 +1,54 @@
#include "Global.h"
#include "classes/IoTItem.h"
#include "Wire.h"
#include "SHT2x.h"
SHT2x* sht = nullptr;
class Sht20t : public IoTItem {
public:
Sht20t(String parameters): IoTItem(parameters) { }
void doByInterval() {
sht->read();
value.valD = sht->getTemperature();
if (value.valD > -46.85F) regEvent(value.valD, "Sht20t");
else SerialPrint("E", "Sensor Sht20t", "Error");
}
~Sht20t() {};
};
class Sht20h : public IoTItem {
public:
Sht20h(String parameters): IoTItem(parameters) { }
void doByInterval() {
sht->read();
value.valD = sht->getHumidity();
if (value.valD != -6) regEvent(value.valD, "Sht20h");
else SerialPrint("E", "Sensor Sht20h", "Error");
}
~Sht20h() {};
};
void* getAPI_Sht20(String subtype, String param) {
if (subtype == F("Sht20t") || subtype == F("Sht20h")) {
if (!sht) {
sht = new SHT2x;
if (sht) sht->begin();
}
if (subtype == F("Sht20t")) {
return new Sht20t(param);
} else if (subtype == F("Sht20h")) {
return new Sht20h(param);
}
} else {
return nullptr;
}
}

View File

@@ -0,0 +1,26 @@
[
{
"name": "Cенсор температуры Sht20",
"num": 3,
"type": "Reading",
"subtype": "Sht20t",
"id": "tmp2",
"widget": "anydataTmp",
"page": "Сенсоры",
"descr": "Температура",
"int": 15,
"round": 1
},
{
"name": "Cенсор влажности Sht20",
"num": 4,
"type": "Reading",
"subtype": "Sht20h",
"id": "Hum2",
"widget": "anydataHum",
"page": "Сенсоры",
"descr": "Влажность",
"int": 15,
"round": 1
}
]

View File

@@ -0,0 +1,7 @@
[env:esp8266_4mb]
lib_deps =
robtillaart/SHT2x@^0.1.1
[env:esp32_4mb]
lib_deps =
robtillaart/SHT2x@^0.1.1

View File

@@ -0,0 +1,5 @@
[
{
"header": "Сенсоры"
}
]