mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-26 22:22:16 +03:00
new BL0937
This commit is contained in:
269
src/modules/sensors/BL0937/BL0937.cpp
Normal file
269
src/modules/sensors/BL0937/BL0937.cpp
Normal file
@@ -0,0 +1,269 @@
|
||||
|
||||
#include "Global.h"
|
||||
#include "classes/IoTItem.h"
|
||||
|
||||
#include "BL0937lib.h"
|
||||
// #include "classes/IoTUart.h"
|
||||
// #include <map>
|
||||
BL0937 *bl0937 = nullptr;
|
||||
|
||||
class BL0937v : public IoTItem
|
||||
{
|
||||
private:
|
||||
public:
|
||||
BL0937v(String parameters) : IoTItem(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
void doByInterval()
|
||||
{
|
||||
if (bl0937)
|
||||
regEvent(bl0937->getVoltage(), "BL0937 V");
|
||||
else
|
||||
{
|
||||
regEvent(NAN, "BL0937v");
|
||||
SerialPrint("E", "BL0937cmd", "initialization error", _id);
|
||||
}
|
||||
}
|
||||
|
||||
~BL0937v(){};
|
||||
};
|
||||
|
||||
class BL0937a : public IoTItem
|
||||
{
|
||||
private:
|
||||
public:
|
||||
BL0937a(String parameters) : IoTItem(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
void doByInterval()
|
||||
{
|
||||
if (bl0937)
|
||||
regEvent(bl0937->getCurrent(), "BL0937 A");
|
||||
else
|
||||
{
|
||||
regEvent(NAN, "BL0937a");
|
||||
SerialPrint("E", "BL0937cmd", "initialization error", _id);
|
||||
}
|
||||
}
|
||||
|
||||
~BL0937a(){};
|
||||
};
|
||||
|
||||
class BL0937w : public IoTItem
|
||||
{
|
||||
private:
|
||||
public:
|
||||
BL0937w(String parameters) : IoTItem(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
void doByInterval()
|
||||
{
|
||||
if (bl0937)
|
||||
regEvent(bl0937->getApparentPower(), "BL0937 W");
|
||||
else
|
||||
{
|
||||
regEvent(NAN, "BL0937w");
|
||||
SerialPrint("E", "BL0937cmd", "initialization error", _id);
|
||||
}
|
||||
}
|
||||
|
||||
~BL0937w(){};
|
||||
};
|
||||
|
||||
class BL0937reactw : public IoTItem
|
||||
{
|
||||
private:
|
||||
public:
|
||||
BL0937reactw(String parameters) : IoTItem(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
void doByInterval()
|
||||
{
|
||||
if (bl0937)
|
||||
regEvent(bl0937->getReactivePower(), "BL0937 reactW");
|
||||
else
|
||||
{
|
||||
regEvent(NAN, "BL0937reactw");
|
||||
SerialPrint("E", "BL0937cmd", "initialization error", _id);
|
||||
}
|
||||
}
|
||||
|
||||
~BL0937reactw(){};
|
||||
};
|
||||
|
||||
class BL0937actw : public IoTItem
|
||||
{
|
||||
private:
|
||||
public:
|
||||
BL0937actw(String parameters) : IoTItem(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
void doByInterval()
|
||||
{
|
||||
if (bl0937)
|
||||
regEvent(bl0937->getActivePower(), "BL0937 actW");
|
||||
else
|
||||
{
|
||||
regEvent(NAN, "BL0937actw");
|
||||
SerialPrint("E", "BL0937cmd", "initialization error", _id);
|
||||
}
|
||||
}
|
||||
|
||||
~BL0937actw(){};
|
||||
};
|
||||
|
||||
class BL0937wh : public IoTItem
|
||||
{
|
||||
private:
|
||||
public:
|
||||
BL0937wh(String parameters) : IoTItem(parameters)
|
||||
{
|
||||
}
|
||||
|
||||
void doByInterval()
|
||||
{
|
||||
if (bl0937)
|
||||
regEvent(bl0937->getEnergy() / 3600.0 / 1000.0, "BL0937 Wh");
|
||||
else
|
||||
{
|
||||
regEvent(NAN, "BL0937wh");
|
||||
SerialPrint("E", "BL0937cmd", "initialization error", _id);
|
||||
}
|
||||
}
|
||||
|
||||
~BL0937wh(){};
|
||||
};
|
||||
|
||||
void ICACHE_RAM_ATTR bl0937_cf1_interrupt()
|
||||
{
|
||||
bl0937->cf1_interrupt();
|
||||
}
|
||||
void ICACHE_RAM_ATTR bl0937_cf_interrupt()
|
||||
{
|
||||
bl0937->cf_interrupt();
|
||||
}
|
||||
|
||||
class BL0937cmd : public IoTItem
|
||||
{
|
||||
private:
|
||||
float CURRENT_RESISTOR = 0.001; // Нужна возможность задавать из веб, это по умолчанию
|
||||
int VOLTAGE_RESISTOR_UPSTREAM = 1000000; // Нужна возможность задавать из веб, это по умолчанию
|
||||
int VOLTAGE_RESISTOR_DOWNSTREAM = 1000; // Нужна возможность задавать из веб, это по умолчанию
|
||||
int BL0937_CF_GPIO = 4; // 8266 12 //Нужна возможность задавать пин из веб, это по умолчанию
|
||||
int BL0937_CF1_GPIO = 5; // 8266 13 //Нужна возможность задавать пин из веб, это по умолчанию
|
||||
int BL0937_SEL_GPIO_INV = 12; // 8266 15 // inverted //Нужна возможность задавать пин из веб, это по умолчанию
|
||||
float _expV = 0;
|
||||
float _expA = 0;
|
||||
float _expW = 0;
|
||||
|
||||
public:
|
||||
BL0937cmd(String parameters) : IoTItem(parameters)
|
||||
{
|
||||
jsonRead(parameters, "R_current", CURRENT_RESISTOR);
|
||||
jsonRead(parameters, "R_upstream", VOLTAGE_RESISTOR_UPSTREAM);
|
||||
jsonRead(parameters, "R_downstream", VOLTAGE_RESISTOR_DOWNSTREAM);
|
||||
jsonRead(parameters, "CF_GPIO", BL0937_CF_GPIO);
|
||||
jsonRead(parameters, "CF1_GPIO", BL0937_CF1_GPIO);
|
||||
jsonRead(parameters, "SEL_GPIO", BL0937_SEL_GPIO_INV);
|
||||
jsonRead(parameters, "expV", _expV);
|
||||
jsonRead(parameters, "expA", _expA);
|
||||
jsonRead(parameters, "expW", _expW);
|
||||
bl0937 = new BL0937;
|
||||
bl0937->begin(BL0937_CF_GPIO, BL0937_CF1_GPIO, BL0937_SEL_GPIO_INV, LOW, true);
|
||||
bl0937->setResistors(CURRENT_RESISTOR, VOLTAGE_RESISTOR_UPSTREAM, VOLTAGE_RESISTOR_DOWNSTREAM);
|
||||
attachInterrupt(BL0937_CF1_GPIO, bl0937_cf1_interrupt, FALLING);
|
||||
attachInterrupt(BL0937_CF_GPIO, bl0937_cf_interrupt, FALLING);
|
||||
if (_expV)
|
||||
bl0937->expectedVoltage(_expV); // для калибровки вольтаж нужно вводить из веб интерфейса
|
||||
if (_expV)
|
||||
bl0937->expectedCurrent(_expA); // для калибровки можно так, а лучше ток вводить из веб интерфейса
|
||||
if (_expV)
|
||||
bl0937->expectedActivePower(_expW); // для калибровки потребляемую мощность нужно вводить из веб интерфейса
|
||||
}
|
||||
|
||||
void doByInterval()
|
||||
{
|
||||
}
|
||||
|
||||
void onModuleOrder(String &key, String &value)
|
||||
{
|
||||
if (bl0937)
|
||||
{
|
||||
if (key == "reset")
|
||||
{
|
||||
bl0937->resetEnergy();
|
||||
SerialPrint("i", "BL0937", "reset energy done");
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
IoTValue execute(String command, std::vector<IoTValue> ¶m)
|
||||
{
|
||||
if (!bl0937)
|
||||
return {};
|
||||
if (command == "calibration")
|
||||
{
|
||||
if (param.size() == 3)
|
||||
{
|
||||
float v = param[0].valD;
|
||||
float a = param[1].valD;
|
||||
float p = param[2].valD;
|
||||
bl0937->expectedVoltage(v); // для калибровки вольтаж нужно вводить из веб интерфейса
|
||||
bl0937->expectedCurrent(a); // для калибровки можно так, а лучше ток вводить из веб интерфейса
|
||||
bl0937->expectedActivePower(p); // для калибровки потребляемую мощность нужно вводить из веб интерфейса
|
||||
return {};
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
*/
|
||||
~BL0937cmd()
|
||||
{
|
||||
if (bl0937)
|
||||
{
|
||||
delete bl0937;
|
||||
bl0937 = nullptr;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void *getAPI_BL0937(String subtype, String param)
|
||||
{
|
||||
if (subtype == F("BL0937v"))
|
||||
{
|
||||
return new BL0937v(param);
|
||||
}
|
||||
else if (subtype == F("BL0937a"))
|
||||
{
|
||||
return new BL0937a(param);
|
||||
}
|
||||
else if (subtype == F("BL0937w"))
|
||||
{
|
||||
return new BL0937w(param);
|
||||
}
|
||||
else if (subtype == F("BL0937wh"))
|
||||
{
|
||||
return new BL0937wh(param);
|
||||
}
|
||||
else if (subtype == F("BL0937reactw"))
|
||||
{
|
||||
return new BL0937reactw(param);
|
||||
}
|
||||
else if (subtype == F("BL0937actw"))
|
||||
{
|
||||
return new BL0937actw(param);
|
||||
}
|
||||
else if (subtype == F("BL0937cmd"))
|
||||
{
|
||||
return new BL0937cmd(param);
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
238
src/modules/sensors/BL0937/BL0937lib.cpp
Normal file
238
src/modules/sensors/BL0937/BL0937lib.cpp
Normal file
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
|
||||
BL0937
|
||||
|
||||
Copyright (C) 2016-2018 by Xose Pérez <xose dot perez at gmail dot com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "BL0937lib.h"
|
||||
|
||||
void BL0937::begin(
|
||||
unsigned char cf_pin,
|
||||
unsigned char cf1_pin,
|
||||
unsigned char sel_pin,
|
||||
unsigned char currentWhen,
|
||||
bool use_interrupts,
|
||||
unsigned long pulse_timeout
|
||||
) {
|
||||
|
||||
_cf_pin = cf_pin;
|
||||
_cf1_pin = cf1_pin;
|
||||
_sel_pin = sel_pin;
|
||||
_current_mode = currentWhen;
|
||||
_use_interrupts = use_interrupts;
|
||||
_pulse_timeout = pulse_timeout;
|
||||
|
||||
pinMode(_cf_pin, INPUT_PULLUP);
|
||||
pinMode(_cf1_pin, INPUT_PULLUP);
|
||||
pinMode(_sel_pin, OUTPUT);
|
||||
|
||||
_calculateDefaultMultipliers();
|
||||
|
||||
_mode = _current_mode;
|
||||
digitalWrite(_sel_pin, _mode);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void BL0937::setMode(bl0937_mode_t mode) {
|
||||
_mode = (mode == MODE_CURRENT) ? _current_mode : 1 - _current_mode;
|
||||
digitalWrite(_sel_pin, _mode);
|
||||
if (_use_interrupts) {
|
||||
_last_cf1_interrupt = _first_cf1_interrupt = micros();
|
||||
}
|
||||
}
|
||||
|
||||
bl0937_mode_t BL0937::getMode() {
|
||||
return (_mode == _current_mode) ? MODE_CURRENT : MODE_VOLTAGE;
|
||||
}
|
||||
|
||||
bl0937_mode_t BL0937::toggleMode() {
|
||||
bl0937_mode_t new_mode = getMode() == MODE_CURRENT ? MODE_VOLTAGE : MODE_CURRENT;
|
||||
setMode(new_mode);
|
||||
return new_mode;
|
||||
}
|
||||
|
||||
double BL0937::getCurrent() {
|
||||
|
||||
// Power measurements are more sensitive to switch offs,
|
||||
// so we first check if power is 0 to set _current to 0 too
|
||||
if (_power == 0) {
|
||||
_current_pulse_width = 0;
|
||||
|
||||
} else if (_use_interrupts) {
|
||||
_checkCF1Signal();
|
||||
|
||||
} else if (_mode == _current_mode) {
|
||||
_current_pulse_width = pulseIn(_cf1_pin, HIGH, _pulse_timeout);
|
||||
}
|
||||
|
||||
_current = (_current_pulse_width > 0) ? _current_multiplier / _current_pulse_width : 0;
|
||||
return _current;
|
||||
|
||||
}
|
||||
|
||||
unsigned int BL0937::getVoltage() {
|
||||
if (_use_interrupts) {
|
||||
_checkCF1Signal();
|
||||
} else if (_mode != _current_mode) {
|
||||
_voltage_pulse_width = pulseIn(_cf1_pin, HIGH, _pulse_timeout);
|
||||
}
|
||||
_voltage = (_voltage_pulse_width > 0) ? _voltage_multiplier / _voltage_pulse_width : 0;
|
||||
return _voltage;
|
||||
}
|
||||
|
||||
unsigned int BL0937::getActivePower() {
|
||||
if (_use_interrupts) {
|
||||
_checkCFSignal();
|
||||
} else {
|
||||
_power_pulse_width = pulseIn(_cf_pin, HIGH, _pulse_timeout);
|
||||
}
|
||||
_power = (_power_pulse_width > 0) ? _power_multiplier / _power_pulse_width : 0;
|
||||
return _power;
|
||||
}
|
||||
|
||||
unsigned int BL0937::getApparentPower() {
|
||||
double current = getCurrent();
|
||||
unsigned int voltage = getVoltage();
|
||||
return voltage * current;
|
||||
}
|
||||
|
||||
unsigned int BL0937::getReactivePower() {
|
||||
unsigned int active = getActivePower();
|
||||
unsigned int apparent = getApparentPower();
|
||||
if (apparent > active) {
|
||||
return sqrt(apparent * apparent - active * active);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
double BL0937::getPowerFactor() {
|
||||
unsigned int active = getActivePower();
|
||||
unsigned int apparent = getApparentPower();
|
||||
if (active > apparent) return 1;
|
||||
if (apparent == 0) return 0;
|
||||
return (double) active / apparent;
|
||||
}
|
||||
|
||||
unsigned long BL0937::getEnergy() {
|
||||
|
||||
// Counting pulses only works in IRQ mode
|
||||
if (!_use_interrupts) return 0;
|
||||
|
||||
/*
|
||||
Pulse count is directly proportional to energy:
|
||||
P = m*f (m=power multiplier, f = Frequency)
|
||||
f = N/t (N=pulse count, t = time)
|
||||
E = P*t = m*N (E=energy)
|
||||
*/
|
||||
return _pulse_count * _power_multiplier / 1000000.0;
|
||||
|
||||
}
|
||||
|
||||
void BL0937::resetEnergy() {
|
||||
_pulse_count = 0;
|
||||
}
|
||||
|
||||
void BL0937::expectedCurrent(double value) {
|
||||
if (_current == 0) getCurrent();
|
||||
if (_current > 0) _current_multiplier *= (value / _current);
|
||||
}
|
||||
|
||||
void BL0937::expectedVoltage(unsigned int value) {
|
||||
if (_voltage == 0) getVoltage();
|
||||
if (_voltage > 0) _voltage_multiplier *= ((double) value / _voltage);
|
||||
}
|
||||
|
||||
void BL0937::expectedActivePower(unsigned int value) {
|
||||
if (_power == 0) getActivePower();
|
||||
if (_power > 0) _power_multiplier *= ((double) value / _power);
|
||||
}
|
||||
|
||||
void BL0937::resetMultipliers() {
|
||||
_calculateDefaultMultipliers();
|
||||
}
|
||||
|
||||
void BL0937::setResistors(double current, double voltage_upstream, double voltage_downstream) {
|
||||
if (voltage_downstream > 0) {
|
||||
_current_resistor = current;
|
||||
_voltage_resistor = (voltage_upstream + voltage_downstream) / voltage_downstream;
|
||||
_calculateDefaultMultipliers();
|
||||
}
|
||||
}
|
||||
|
||||
void ICACHE_RAM_ATTR BL0937::cf_interrupt() {
|
||||
unsigned long now = micros();
|
||||
_power_pulse_width = now - _last_cf_interrupt;
|
||||
_last_cf_interrupt = now;
|
||||
_pulse_count++;
|
||||
}
|
||||
|
||||
void ICACHE_RAM_ATTR BL0937::cf1_interrupt() {
|
||||
|
||||
unsigned long now = micros();
|
||||
|
||||
if ((now - _first_cf1_interrupt) > _pulse_timeout) {
|
||||
|
||||
unsigned long pulse_width;
|
||||
|
||||
if (_last_cf1_interrupt == _first_cf1_interrupt) {
|
||||
pulse_width = 0;
|
||||
} else {
|
||||
pulse_width = now - _last_cf1_interrupt;
|
||||
}
|
||||
|
||||
if (_mode == _current_mode) {
|
||||
_current_pulse_width = pulse_width;
|
||||
} else {
|
||||
_voltage_pulse_width = pulse_width;
|
||||
}
|
||||
|
||||
_mode = 1 - _mode;
|
||||
digitalWrite(_sel_pin, _mode);
|
||||
_first_cf1_interrupt = now;
|
||||
|
||||
}
|
||||
|
||||
_last_cf1_interrupt = now;
|
||||
|
||||
}
|
||||
|
||||
void BL0937::_checkCFSignal() {
|
||||
if ((micros() - _last_cf_interrupt) > _pulse_timeout) _power_pulse_width = 0;
|
||||
}
|
||||
|
||||
void BL0937::_checkCF1Signal() {
|
||||
if ((micros() - _last_cf1_interrupt) > _pulse_timeout) {
|
||||
if (_mode == _current_mode) {
|
||||
_current_pulse_width = 0;
|
||||
} else {
|
||||
_voltage_pulse_width = 0;
|
||||
}
|
||||
toggleMode();
|
||||
}
|
||||
}
|
||||
|
||||
// These are the multipliers for current, voltage and power as per datasheet
|
||||
// These values divided by output period (in useconds) give the actual value
|
||||
void BL0937::_calculateDefaultMultipliers() {
|
||||
_current_multiplier = ( 1000000.0 * 512 * V_REF / _current_resistor / 24.0 / F_OSC ) * 0.850112464f;
|
||||
_voltage_multiplier = ( 1000000.0 * 512 * V_REF * _voltage_resistor / 2.0 / F_OSC) * 0.863158011f;
|
||||
_power_multiplier = ( 1000000.0 * 128 * V_REF * V_REF * _voltage_resistor / _current_resistor / 48.0 / F_OSC) * 0.713465334f;
|
||||
}
|
||||
146
src/modules/sensors/BL0937/BL0937lib.h
Normal file
146
src/modules/sensors/BL0937/BL0937lib.h
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
|
||||
BL0937
|
||||
|
||||
Copyright (C) 2016-2018 by Xose Pérez <xose dot perez at gmail dot com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef BL0937_h
|
||||
#define BL0937_h
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
// Internal voltage reference value
|
||||
#define V_REF 1.218
|
||||
|
||||
// The factor of a 1mOhm resistor
|
||||
// as per recomended circuit in datasheet
|
||||
// A 1mOhm resistor allows a ~30A max measurement
|
||||
#define R_CURRENT 0.001
|
||||
|
||||
// This is the factor of a voltage divider of 1MOhm upstream and 1kOhm downstream
|
||||
// as per recomended circuit in datasheet
|
||||
#define R_VOLTAGE 1000
|
||||
|
||||
// Frequency of the BL0937 internal clock
|
||||
#define F_OSC 2000000
|
||||
|
||||
// Minimum delay between selecting a mode and reading a sample
|
||||
#define READING_INTERVAL 3000
|
||||
|
||||
// Maximum pulse with in microseconds
|
||||
// If longer than this pulse width is reset to 0
|
||||
// This value is purely experimental.
|
||||
// Higher values allow for a better precission but reduce sampling rate
|
||||
// and response speed to change
|
||||
// Lower values increase sampling rate but reduce precission
|
||||
// Values below 0.5s are not recommended since current and voltage output
|
||||
// will have no time to stabilise
|
||||
#define PULSE_TIMEOUT 5000000
|
||||
|
||||
// Define ICACHE_RAM_ATTR for AVR platforms
|
||||
#if defined(ARDUINO_ARCH_AVR)
|
||||
#define ICACHE_RAM_ATTR
|
||||
#endif
|
||||
|
||||
// CF1 mode
|
||||
typedef enum {
|
||||
MODE_CURRENT,
|
||||
MODE_VOLTAGE
|
||||
} bl0937_mode_t;
|
||||
|
||||
class BL0937 {
|
||||
|
||||
public:
|
||||
|
||||
void cf_interrupt();
|
||||
void cf1_interrupt();
|
||||
|
||||
void begin(
|
||||
unsigned char cf_pin,
|
||||
unsigned char cf1_pin,
|
||||
unsigned char sel_pin,
|
||||
unsigned char currentWhen = HIGH,
|
||||
bool use_interrupts = true,
|
||||
unsigned long pulse_timeout = PULSE_TIMEOUT);
|
||||
|
||||
void setMode(bl0937_mode_t mode);
|
||||
bl0937_mode_t getMode();
|
||||
bl0937_mode_t toggleMode();
|
||||
|
||||
double getCurrent();
|
||||
unsigned int getVoltage();
|
||||
unsigned int getActivePower();
|
||||
unsigned int getApparentPower();
|
||||
double getPowerFactor();
|
||||
unsigned int getReactivePower();
|
||||
unsigned long getEnergy(); //in Ws
|
||||
void resetEnergy();
|
||||
|
||||
void setResistors(double current, double voltage_upstream, double voltage_downstream);
|
||||
|
||||
void expectedCurrent(double current);
|
||||
void expectedVoltage(unsigned int current);
|
||||
void expectedActivePower(unsigned int power);
|
||||
|
||||
double getCurrentMultiplier() { return _current_multiplier; };
|
||||
double getVoltageMultiplier() { return _voltage_multiplier; };
|
||||
double getPowerMultiplier() { return _power_multiplier; };
|
||||
|
||||
void setCurrentMultiplier(double current_multiplier) { _current_multiplier = current_multiplier; };
|
||||
void setVoltageMultiplier(double voltage_multiplier) { _voltage_multiplier = voltage_multiplier; };
|
||||
void setPowerMultiplier(double power_multiplier) { _power_multiplier = power_multiplier; };
|
||||
void resetMultipliers();
|
||||
|
||||
private:
|
||||
|
||||
unsigned char _cf_pin;
|
||||
unsigned char _cf1_pin;
|
||||
unsigned char _sel_pin;
|
||||
|
||||
double _current_resistor = R_CURRENT;
|
||||
double _voltage_resistor = R_VOLTAGE;
|
||||
|
||||
double _current_multiplier; // Unit: us/A
|
||||
double _voltage_multiplier; // Unit: us/V
|
||||
double _power_multiplier; // Unit: us/W
|
||||
|
||||
unsigned long _pulse_timeout = PULSE_TIMEOUT; //Unit: us
|
||||
volatile unsigned long _voltage_pulse_width = 0; //Unit: us
|
||||
volatile unsigned long _current_pulse_width = 0; //Unit: us
|
||||
volatile unsigned long _power_pulse_width = 0; //Unit: us
|
||||
volatile unsigned long _pulse_count = 0;
|
||||
|
||||
double _current = 0;
|
||||
unsigned int _voltage = 0;
|
||||
unsigned int _power = 0;
|
||||
|
||||
unsigned char _current_mode = HIGH;
|
||||
volatile unsigned char _mode;
|
||||
|
||||
bool _use_interrupts = true;
|
||||
volatile unsigned long _last_cf_interrupt = 0;
|
||||
volatile unsigned long _last_cf1_interrupt = 0;
|
||||
volatile unsigned long _first_cf1_interrupt = 0;
|
||||
|
||||
void _checkCFSignal();
|
||||
void _checkCF1Signal();
|
||||
void _calculateDefaultMultipliers();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
129
src/modules/sensors/BL0937/modinfo.json
Normal file
129
src/modules/sensors/BL0937/modinfo.json
Normal file
@@ -0,0 +1,129 @@
|
||||
{
|
||||
"menuSection": "sensors",
|
||||
"configItem": [
|
||||
{
|
||||
"global": 0,
|
||||
"name": "BL0937 Напряжение",
|
||||
"type": "Reading",
|
||||
"subtype": "BL0937v",
|
||||
"id": "bl_v",
|
||||
"widget": "anydataVlt",
|
||||
"page": "BL0937",
|
||||
"descr": "Напряжение",
|
||||
"int": 15,
|
||||
"round": 1
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"name": "BL0937 Сила тока",
|
||||
"type": "Reading",
|
||||
"subtype": "BL0937a",
|
||||
"id": "bl_a",
|
||||
"widget": "anydataAmp",
|
||||
"page": "BL0937",
|
||||
"descr": "Сила тока",
|
||||
"int": 15,
|
||||
"round": 1
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"name": "BL0937 Мощность",
|
||||
"type": "Reading",
|
||||
"subtype": "BL0937w",
|
||||
"id": "bl_w",
|
||||
"widget": "anydataWt",
|
||||
"page": "BL0937",
|
||||
"descr": "Мощность",
|
||||
"int": 15,
|
||||
"round": 1
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"name": "BL0937 Реакт.Мощность",
|
||||
"type": "Reading",
|
||||
"subtype": "BL0937reactw",
|
||||
"id": "bl_w",
|
||||
"widget": "anydataWt",
|
||||
"page": "BL0937",
|
||||
"descr": "Реакт.Мощность",
|
||||
"int": 15,
|
||||
"round": 1
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"name": "BL0937 Активн.Мощность",
|
||||
"type": "Reading",
|
||||
"subtype": "BL0937actw",
|
||||
"id": "bl_actw",
|
||||
"widget": "anydataWt",
|
||||
"page": "BL0937",
|
||||
"descr": "Актив.Мощность",
|
||||
"int": 15,
|
||||
"round": 1
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"name": "BL0937 Энергия",
|
||||
"type": "Reading",
|
||||
"subtype": "BL0937wh",
|
||||
"id": "bl_wh",
|
||||
"widget": "anydataWth",
|
||||
"page": "BL0937",
|
||||
"descr": "Энергия",
|
||||
"int": 15,
|
||||
"round": 1
|
||||
},
|
||||
{
|
||||
"global": 0,
|
||||
"name": "BL0937 настройка",
|
||||
"type": "Reading",
|
||||
"subtype": "BL0937cmd",
|
||||
"id": "bl_set",
|
||||
"widget": "nil",
|
||||
"page": "",
|
||||
"descr": "",
|
||||
"btn-reset": "",
|
||||
"R_current": 0.001,
|
||||
"R_upstream": 1000000,
|
||||
"R_downstream": 1000,
|
||||
"CF_GPIO": 4,
|
||||
"CF1_GPIO": 5,
|
||||
"SEL_GPIO": 12,
|
||||
"expV": 0,
|
||||
"expA": 0,
|
||||
"expW": 0
|
||||
}
|
||||
],
|
||||
"about": {
|
||||
"authorName": "Bubnov Mikhail",
|
||||
"authorContact": "https://t.me/Mit4bmw",
|
||||
"authorGit": "https://github.com/Mit4el",
|
||||
"specialThanks": "",
|
||||
"moduleName": "BL0937",
|
||||
"moduleVersion": "1.0",
|
||||
"usedRam": {
|
||||
"esp32_4mb": 15,
|
||||
"esp8266_4mb": 15
|
||||
},
|
||||
"title": "Счетчик электроэнергии BL0937",
|
||||
"moduleDesc": "Считает потраченную электроэнергию, измеряет напряжение, силу тока и прочие параметры.",
|
||||
"propInfo": {
|
||||
"int": "Количество секунд между опросами датчика.",
|
||||
"btn-reset": "Энергия BL0937 будет сброшена к нулю.",
|
||||
"R_current": "Резистор подключенный последовательно к основной линии",
|
||||
"R_upstream": "это 5 резисторов по 470 Ком в делителе напряжения, который питает вывод V2P",
|
||||
"R_downstream": "это резистор емкостью 1 Ком в делителе напряжения, который питает вывод V2P",
|
||||
"CF_GPIO": "пин CF",
|
||||
"CF1_GPIO": "пин CF1",
|
||||
"SEL_GPIO": "пин SEL",
|
||||
"expV": "реальное напряжение, указать для калибровки",
|
||||
"expA": "реальный ток, указать для калибровки",
|
||||
"expW": "реальная мощность, указать для калибровки"
|
||||
}
|
||||
},
|
||||
"defActive": true,
|
||||
"usedLibs": {
|
||||
"esp32*": [],
|
||||
"esp82*": []
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user