mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-26 22:22:16 +03:00
@@ -3,6 +3,14 @@
|
|||||||
|
|
||||||
extern IoTGpio IoTgpio;
|
extern IoTGpio IoTgpio;
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
#define SC_ADC 4095. //Scale ADC
|
||||||
|
#else
|
||||||
|
#define SC_ADC 1023. //Scale ADC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DEF_NAN 50 //количество отсчетов АПЦ которые мы принимаем за отсутствие датчика (в идеале 0, но все равно Acs712 выдает минимум 0,5В)
|
||||||
|
|
||||||
class Acs712 : public IoTItem
|
class Acs712 : public IoTItem
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@@ -10,56 +18,97 @@ private:
|
|||||||
const unsigned long _sampleTime = 100000UL; // sample over 100ms, it is an exact number of cycles for both 50Hz and 60Hz mains
|
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 _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
|
const unsigned long _sampleInterval = _sampleTime / _numSamples; // the sampling interval, must be longer than then ADC conversion time
|
||||||
int _adc_zero1; //Переменная автоматической калибровки
|
int _adc_zero1; // Переменная автоматической калибровки
|
||||||
|
int _fl_rms; // 1 - подсчет средне-квадратического тока (переменный), 0 - подсчет средне-арифмитического тока (постоянный)
|
||||||
|
int _sens = 100; //Чувствительность датчика тока: 5A = 185mВ/A, 20A = 100mВ/A, 30A = 66mВ/A
|
||||||
|
int _vref; //"Vref (мВ) - Опороное наряжение питания Acs712, по умолчанию = 5000мВ",
|
||||||
|
float k ; //Чувствительность(разрешение) Acs712 по току, сколько тока в одном отсчете АЦП, k=VACP/sens (30А->74mА, 20A->49mA, 5A->26mA для esp8266)
|
||||||
|
bool f_nan = false; //Флаг отсутствия входа на АЦП
|
||||||
|
float vacp; //Напряжение в мВ для смещения одного разряда АЦП esp8266 = 4.887, esp32 = 1.221; vacp = vcc*1000/1023
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Acs712(String parameters) : IoTItem(parameters)
|
Acs712(String parameters) : IoTItem(parameters)
|
||||||
{
|
{
|
||||||
String tmp;
|
String tmp;
|
||||||
jsonRead(parameters, "pin", tmp);
|
jsonRead(parameters, "pin", tmp);
|
||||||
_pin = tmp.toInt();
|
_pin = tmp.toInt();
|
||||||
_adc_zero1 = determineVQ(_pin);
|
jsonRead(parameters, "adczero", tmp);
|
||||||
|
_adc_zero1 = tmp.toInt(); // determineVQ(_pin);
|
||||||
|
jsonRead(parameters, "rms", tmp);
|
||||||
|
_fl_rms = tmp.toInt();
|
||||||
|
jsonRead(parameters, "sens", tmp);
|
||||||
|
_sens = tmp.toInt();
|
||||||
|
jsonRead(parameters, "vref", tmp);
|
||||||
|
_vref = tmp.toInt();
|
||||||
|
vacp = _vref/SC_ADC;
|
||||||
|
k = vacp / (float)_sens; //коэффециент для домножения измерений АЦП
|
||||||
}
|
}
|
||||||
|
|
||||||
void doByInterval()
|
void doByInterval()
|
||||||
{
|
{
|
||||||
|
f_nan = false;
|
||||||
unsigned long currentAcc = 0;
|
unsigned long currentAcc = 0;
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
unsigned long prevMicros = micros() - _sampleInterval;
|
unsigned long prevMicros = micros() - _sampleInterval;
|
||||||
while (count < _numSamples)
|
while (count < _numSamples)
|
||||||
|
{
|
||||||
|
if (micros() - prevMicros >= _sampleInterval)
|
||||||
{
|
{
|
||||||
if (micros() - prevMicros >= _sampleInterval)
|
int adc_raw = IoTgpio.analogRead(_pin);
|
||||||
{
|
if (adc_raw > DEF_NAN) f_nan = true; //Если за цикл измерений не было АЦП больше 50, то считаем что нет датчика
|
||||||
int adc_raw = IoTgpio.analogRead(_pin) - _adc_zero1;
|
adc_raw -= _adc_zero1;
|
||||||
|
if (_fl_rms == 0)
|
||||||
|
currentAcc += (unsigned long)abs(adc_raw);
|
||||||
|
else
|
||||||
currentAcc += (unsigned long)(adc_raw * adc_raw);
|
currentAcc += (unsigned long)(adc_raw * adc_raw);
|
||||||
++count;
|
++count;
|
||||||
prevMicros += _sampleInterval;
|
prevMicros += _sampleInterval;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#ifdef ESP32
|
}
|
||||||
value.valD = int(sqrt((float)currentAcc / (float)_numSamples) * (75.7576 / 4095.0));
|
|
||||||
#else
|
if (_fl_rms == 0)
|
||||||
value.valD = int(sqrt((float)currentAcc / (float)_numSamples) * (75.7576 / 1023.0));
|
{
|
||||||
#endif
|
#ifdef ESP32
|
||||||
|
value.valD = ((float)currentAcc / (float)_numSamples) * k;
|
||||||
|
#else
|
||||||
|
value.valD = ((float)currentAcc / (float)_numSamples) * k;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef ESP32
|
||||||
|
value.valD = (sqrt((float)currentAcc / (float)_numSamples) * k);
|
||||||
|
#else
|
||||||
|
value.valD = (sqrt((float)currentAcc / (float)_numSamples) * k);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (f_nan)
|
||||||
regEvent(value.valD, "Acs712");
|
regEvent(value.valD, "Acs712");
|
||||||
|
else
|
||||||
|
regEvent(NAN, "Acs712");
|
||||||
|
}
|
||||||
|
|
||||||
|
void onModuleOrder(String &key, String &value)
|
||||||
|
{
|
||||||
|
if (key == "setZero")
|
||||||
|
{
|
||||||
|
_adc_zero1 = determineVQ(_pin);
|
||||||
|
SerialPrint("i", F("Acs712"), "User run calibration ADC zero: " + String(_adc_zero1));
|
||||||
|
// TODO wtitejson to config.json?????
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int determineVQ(int PIN)
|
int determineVQ(int PIN)
|
||||||
{
|
{
|
||||||
long VQ = 0;
|
long VQ = 0;
|
||||||
// read 5000 samples to stabilise value
|
for (int i = 0; i < 100; i++)
|
||||||
for (int i = 0; i < 5000; i++)
|
|
||||||
{
|
{
|
||||||
VQ += IoTgpio.analogRead(PIN);
|
VQ += IoTgpio.analogRead(PIN);
|
||||||
//delay(1); // depends on sampling (on filter capacitor), can be 1/80000 (80kHz) max.
|
|
||||||
}
|
}
|
||||||
VQ /= 5000;
|
VQ /= 100;
|
||||||
return int(VQ);
|
return int(VQ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
~Acs712(){};
|
~Acs712(){};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -11,26 +11,42 @@
|
|||||||
"descr": "Ток",
|
"descr": "Ток",
|
||||||
"round": 3,
|
"round": 3,
|
||||||
"pin": 39,
|
"pin": 39,
|
||||||
"int": 5
|
"int": 5,
|
||||||
|
"rms": 1,
|
||||||
|
"vref": 5000,
|
||||||
|
"sens": 100,
|
||||||
|
"adczero" : 512,
|
||||||
|
"btn-setZero": "nil"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"about": {
|
"about": {
|
||||||
"authorName": "Yuriy Kuneev",
|
"authorName": "Bubnov Mikhail",
|
||||||
"authorContact": "https://t.me/Kuneev07",
|
"authorContact": "https://t.me/Mitchel",
|
||||||
"authorGit": "",
|
"authorGit": "https://github.com/Mit4el",
|
||||||
"exampleURL": "https://iotmanager.org/wiki",
|
"exampleURL": "https://iotmanager.org/wiki",
|
||||||
"specialThanks": "",
|
"specialThanks": "",
|
||||||
"moduleName": "Acs712",
|
"moduleName": "Acs712",
|
||||||
"moduleVersion": "1.0",
|
"moduleVersion": "2.0",
|
||||||
"moduleDesc": "Позволяет получить текущее значение тока на аналоговом пине с помощью модуля Acs712.",
|
"moduleDesc": "Позволяет получить текущее значение тока на аналоговом пине с помощью модуля Acs712. Не забываем про делитель для входа на АЦП/",
|
||||||
"propInfo": {
|
"propInfo": {
|
||||||
"pin": "Аналоговый GPIO номер, к которому подключен датчик.",
|
"pin": "Аналоговый GPIO номер, к которому подключен датчик. Для esp8266 0",
|
||||||
"int": "Количество секунд между опросами датчика."
|
"int": "Количество секунд между опросами датчика.",
|
||||||
|
"rms": "1 - подсчет средне-квадратического тока (переменный), 0 - подсчет средне-арифмитического тока (постоянный)",
|
||||||
|
"vref": "Vref (мВ) - Опороное наряжение питания Acs712, по умолчанию = 5000мВ",
|
||||||
|
"sens": "Чувствительность датчика тока: 5A = 185mВ/A , 20A = 100mВ/A , 30A = 66mВ/A ",
|
||||||
|
"adczero" : "Переменная калибровки нулевого значения отсчетов АЦП при нулевой нагрузке. Для ESP8266 - 512, Для ESP32 -2048, это 2.5В = 0А (1,65 с делителем) для Acs712 20A и 30A при стабильном токе 5В",
|
||||||
|
"btn-setZero": "Кнопка калибровки нулевого значения отсчетов АЦП при нулевой нагрузке. Нагрузка в момент калибровки должна быть отключена! После перезагрузки будет установлено в значение по умолчанию adczero. Для сохранение смотрим лог, и изменияем adczero"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"defActive": true,
|
"defActive": true,
|
||||||
"usedLibs": {
|
"usedLibs": {
|
||||||
"esp32_4mb": [],
|
"esp32_4mb": [],
|
||||||
"esp8266_4mb": []
|
"esp8266_4mb": [],
|
||||||
|
"esp8266_1mb": [],
|
||||||
|
"esp8266_1mb_ota": [],
|
||||||
|
"esp8285_1mb": [],
|
||||||
|
"esp8285_1mb_ota": [],
|
||||||
|
"esp8266_2mb": [],
|
||||||
|
"esp8266_2mb_ota": []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -119,7 +119,7 @@
|
|||||||
"moduleDesc": "Считает потраченную электроэнергию, измеряет напряжение, частоту, силу тока и прочие параметры",
|
"moduleDesc": "Считает потраченную электроэнергию, измеряет напряжение, частоту, силу тока и прочие параметры",
|
||||||
"propInfo": {
|
"propInfo": {
|
||||||
"addr": "Адрес modbus",
|
"addr": "Адрес modbus",
|
||||||
"int": "Количество секунд между опросами датчика. Желателно устанавливать разные интервалы для параметров что бы опросы происходили в разное время.",
|
"int": "Количество секунд между опросами датчика. Желателно устанавливать одинаковые интервалы для параметров (для одного адреса Pzem) что опрос происходил один раз, остальные из 500мс буфера.",
|
||||||
"changeaddr": "Поставьте этот параметр равным 1 и перезагрузите esp - будет установлен адрес указанный в setaddr. Смотрите в логе результат: [i] Pzem address set: 0x01",
|
"changeaddr": "Поставьте этот параметр равным 1 и перезагрузите esp - будет установлен адрес указанный в setaddr. Смотрите в логе результат: [i] Pzem address set: 0x01",
|
||||||
"setaddr": "Новый адрес который нужно назначить",
|
"setaddr": "Новый адрес который нужно назначить",
|
||||||
"reset": "Поставьте этот параметр равным 1 и pzem будет сброшен к нулю. Смотрите в логе результат: [i] Pzem reset done"
|
"reset": "Поставьте этот параметр равным 1 и pzem будет сброшен к нулю. Смотрите в логе результат: [i] Pzem reset done"
|
||||||
|
|||||||
Reference in New Issue
Block a user