mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-27 22:52:19 +03:00
126 lines
4.8 KiB
C++
126 lines
4.8 KiB
C++
#include "Global.h"
|
||
#include "classes/IoTItem.h"
|
||
|
||
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
|
||
{
|
||
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; // Переменная автоматической калибровки
|
||
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:
|
||
Acs712(String parameters) : IoTItem(parameters)
|
||
{
|
||
String tmp;
|
||
jsonRead(parameters, "pin", tmp);
|
||
_pin = tmp.toInt();
|
||
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()
|
||
{
|
||
f_nan = false;
|
||
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);
|
||
if (adc_raw > DEF_NAN) f_nan = true; //Если за цикл измерений не было АЦП больше 50, то считаем что нет датчика
|
||
adc_raw -= _adc_zero1;
|
||
if (_fl_rms == 0)
|
||
currentAcc += (unsigned long)abs(adc_raw);
|
||
else
|
||
currentAcc += (unsigned long)(adc_raw * adc_raw);
|
||
++count;
|
||
prevMicros += _sampleInterval;
|
||
}
|
||
}
|
||
|
||
if (_fl_rms == 0)
|
||
{
|
||
#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");
|
||
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)
|
||
{
|
||
long VQ = 0;
|
||
for (int i = 0; i < 100; i++)
|
||
{
|
||
VQ += IoTgpio.analogRead(PIN);
|
||
}
|
||
VQ /= 100;
|
||
return int(VQ);
|
||
}
|
||
|
||
~Acs712(){};
|
||
};
|
||
|
||
void *getAPI_Acs712(String subtype, String param)
|
||
{
|
||
if (subtype == F("Acs712"))
|
||
{
|
||
return new Acs712(param);
|
||
}
|
||
else
|
||
{
|
||
return nullptr;
|
||
}
|
||
}
|