Browse Source

sns: similar updates to pulse meter

pull/2516/head
Maxim Prokhorov 2 years ago
parent
commit
20203633ed
2 changed files with 45 additions and 34 deletions
  1. +2
    -1
      code/espurna/sensor.cpp
  2. +43
    -33
      code/espurna/sensors/PulseMeterSensor.h

+ 2
- 1
code/espurna/sensor.cpp View File

@ -2935,7 +2935,8 @@ void _sensorLoad() {
PulseMeterSensor * sensor = new PulseMeterSensor();
sensor->setGPIO(PULSEMETER_PIN);
sensor->setInterruptMode(PULSEMETER_INTERRUPT_ON);
sensor->setDebounceTime(PULSEMETER_DEBOUNCE);
sensor->setDebounceTime(
PulseMeterSensor::TimeSource::duration{PULSEMETER_DEBOUNCE});
_sensors.push_back(sensor);
}
#endif


+ 43
- 33
code/espurna/sensors/PulseMeterSensor.h View File

@ -14,6 +14,8 @@ class PulseMeterSensor : public BaseEmonSensor {
public:
using TimeSource = espurna::time::CpuClock;
// ---------------------------------------------------------------------
// Public
// ---------------------------------------------------------------------
@ -23,11 +25,9 @@ class PulseMeterSensor : public BaseEmonSensor {
MAGNITUDE_ENERGY
};
PulseMeterSensor() {
_sensor_id = SENSOR_PULSEMETER_ID;
_count = std::size(Magnitudes);
findAndAddEnergy(Magnitudes);
}
PulseMeterSensor() :
BaseEmonSensor(Magnitudes)
{}
// ---------------------------------------------------------------------
@ -41,21 +41,22 @@ class PulseMeterSensor : public BaseEmonSensor {
_interrupt_mode = interrupt_mode;
}
void setDebounceTime(unsigned long debounce) {
_interrupt_debounce = debounce;
template <typename T>
void setDebounceTime(T debounce) {
_interrupt_debounce = std::chrono::duration_cast<TimeSource::duration>(debounce);
}
// ---------------------------------------------------------------------
unsigned char getGPIO() {
unsigned char getGPIO() const {
return _pin.pin();
}
unsigned char getInterruptMode() {
unsigned char getInterruptMode() const {
return _interrupt_mode;
}
unsigned long getDebounceTime() {
TimeSource::duration getDebounceTime() const {
return _interrupt_debounce;
}
@ -63,45 +64,50 @@ class PulseMeterSensor : public BaseEmonSensor {
// Sensors API
// ---------------------------------------------------------------------
unsigned char id() const override {
return SENSOR_PULSEMETER_ID;
}
unsigned char count() const override {
return std::size(Magnitudes);
}
// Initialization method, must be idempotent
// Defined outside the class body
void begin() {
void begin() override {
_previous_time = TimeSource::now();
_enableInterrupts();
_ready = true;
}
// Descriptive name of the sensor
String description() {
String description() const override {
char buffer[24];
snprintf_P(buffer, sizeof(buffer),
PSTR("PulseMeter @ GPIO(%hhu)"), _pin.pin());
return String(buffer);
}
// Descriptive name of the slot # index
String description(unsigned char index) {
return description();
};
// Address of the sensor (it could be the GPIO or I2C address)
String address(unsigned char index) {
String address(unsigned char) const override {
return String(_pin);
}
// Pre-read hook (usually to populate registers with up-to-date data)
void pre() {
unsigned long lapse = millis() - _previous_time;
_previous_time = millis();
void pre() override {
const auto now = TimeSource::now();
const auto elapsed = now - _previous_time;
_previous_time = now;
auto reading = *(reinterpret_cast<volatile unsigned long*>(&_pulses));
const auto reading = *(reinterpret_cast<volatile unsigned long*>(&_pulses));
unsigned long pulses = reading - _previous_pulses;
_previous_pulses = reading;
sensor::Ws delta = 1000.0 * 3600.0 * static_cast<double>(pulses) / _energy_ratio;
_energy[0] += delta;
if (lapse > 0) {
_active = 1000.0 * delta.value / lapse;
if (elapsed.count()) {
const auto milliseconds = std::chrono::duration_cast<espurna::duration::Milliseconds>(elapsed).count();
_active = 1000.0 * delta.value / milliseconds;
}
}
@ -129,7 +135,7 @@ class PulseMeterSensor : public BaseEmonSensor {
}
// Type for slot # index
unsigned char type(unsigned char index) {
unsigned char type(unsigned char index) const override {
if (index < std::size(Magnitudes)) {
return Magnitudes[index].type;
}
@ -138,7 +144,7 @@ class PulseMeterSensor : public BaseEmonSensor {
}
// Current value for slot # index
double value(unsigned char index) {
double value(unsigned char index) override {
if (index == 0) return _active;
if (index == 1) return _energy[0].asDouble();
return 0;
@ -146,8 +152,9 @@ class PulseMeterSensor : public BaseEmonSensor {
// Handle interrupt calls
void IRAM_ATTR interrupt() {
if (millis() - _interrupt_last > _interrupt_debounce) {
_interrupt_last = millis();
const auto now = TimeSource::now();
if (now - _interrupt_last > _interrupt_debounce) {
_interrupt_last = now;
++_pulses;
}
}
@ -156,13 +163,14 @@ class PulseMeterSensor : public BaseEmonSensor {
instance->interrupt();
}
protected:
private:
// ---------------------------------------------------------------------
// Interrupt management
// ---------------------------------------------------------------------
void _enableInterrupts() {
_interrupt_last = TimeSource::now();
_pin.attach(this, handleInterrupt, _interrupt_mode);
}
@ -176,12 +184,14 @@ class PulseMeterSensor : public BaseEmonSensor {
unsigned long _pulses = 0;
unsigned long _previous_pulses = 0;
unsigned long _previous_time = 0;
TimeSource::time_point _interrupt_last;
TimeSource::duration _interrupt_debounce;
TimeSource::time_point _previous_time;
InterruptablePin _pin;
int _interrupt_mode = FALLING;
unsigned long _interrupt_last = 0;
unsigned long _interrupt_debounce = PULSEMETER_DEBOUNCE;
};
#if __cplusplus < 201703L


Loading…
Cancel
Save