diff --git a/data_svelte/widgets.json b/data_svelte/widgets.json index 5470c3bc..b4cf75cd 100644 --- a/data_svelte/widgets.json +++ b/data_svelte/widgets.json @@ -209,6 +209,13 @@ ], "status": 0 }, + { + "name": "anydataPpm", + "label": "PPM", + "widget": "anydata", + "after": "ppm", + "icon": "speedometer" + }, { "name": "nil", "label": "Без виджета" diff --git a/src/modules/sensors/Acs712/Acs712.cpp b/src/modules/sensors/Acs712/Acs712.cpp new file mode 100644 index 00000000..79d9bc76 --- /dev/null +++ b/src/modules/sensors/Acs712/Acs712.cpp @@ -0,0 +1,76 @@ +#include "Global.h" +#include "classes/IoTItem.h" + +extern IoTGpio IoTgpio; + +class Acs712 : public IoTItem +{ +private: + unsigned int _pin; + const unsigned long _sampleTime = 100000UL; // sample over 100ms, it is an exact number of cycles for both 50Hz and 60Hz mains + const unsigned long _numSamples = 250UL; // choose the number of samples to divide sampleTime exactly, but low enough for the ADC to keep up + const unsigned long _sampleInterval = _sampleTime / _numSamples; // the sampling interval, must be longer than then ADC conversion time + int _adc_zero1; //Переменная автоматической калибровки + +public: + + Acs712(String parameters) : IoTItem(parameters) + { + String tmp; + jsonRead(parameters, "pin", tmp); + _pin = tmp.toInt(); + _adc_zero1 = determineVQ(_pin); + } + + void doByInterval() + { + + unsigned long currentAcc = 0; + unsigned int count = 0; + unsigned long prevMicros = micros() - _sampleInterval; + while (count < _numSamples) + { + if (micros() - prevMicros >= _sampleInterval) + { + int adc_raw = IoTgpio.analogRead(_pin) - _adc_zero1; + currentAcc += (unsigned long)(adc_raw * adc_raw); + ++count; + prevMicros += _sampleInterval; + } + } + #ifdef ESP32 + value.valD = int(sqrt((float)currentAcc / (float)_numSamples) * (75.7576 / 4095.0)); + #else + value.valD = int(sqrt((float)currentAcc / (float)_numSamples) * (75.7576 / 1023.0)); + #endif + regEvent(value.valD, "Acs712"); + } + + int determineVQ(int PIN) + { + long VQ = 0; + // read 5000 samples to stabilise value + for (int i = 0; i < 5000; i++) + { + VQ += IoTgpio.analogRead(PIN); + //delay(1); // depends on sampling (on filter capacitor), can be 1/80000 (80kHz) max. + } + VQ /= 5000; + return int(VQ); + } + + + ~Acs712(){}; +}; + +void *getAPI_Acs712(String subtype, String param) +{ + if (subtype == F("Acs712")) + { + return new Acs712(param); + } + else + { + return nullptr; + } +} diff --git a/src/modules/sensors/Acs712/modinfo.json b/src/modules/sensors/Acs712/modinfo.json new file mode 100644 index 00000000..f85cb8db --- /dev/null +++ b/src/modules/sensors/Acs712/modinfo.json @@ -0,0 +1,41 @@ +{ + "menuSection": "Сенсоры", + + "configItem": [{ + "name": "Аналоговый датчик тока Acs712", + "type": "Reading", + "subtype": "Acs712", + "id": "amp", + "widget": "anydataAmp", + "page": "Сенсоры", + "descr": "Ток", + "round": 3, + "pin": 39, + "int": 5 + }], + + "about": { + "authorName": "Yuriy Kuneev", + "authorContact": "https://t.me/Kuneev07", + "authorGit": "", + "exampleURL": "https://iotmanager.org/wiki", + "specialThanks": "", + "moduleName": "Acs712", + "moduleVersion": "1.0", + "moduleDesc": "Позволяет получить текущее значение тока на аналоговом пине с помощью модуля Acs712.", + "propInfo": { + "pin": "Аналоговый GPIO номер, к которому подключен датчик.", + "int": "Количество секунд между опросами датчика." + } + }, + + + + "defActive": true, + + "devices": { + "esp32_4mb": [], + "esp8266_4mb": [] + } +} +