Browse Source

Ported V9261F power sensor to new sensors

fastled
Xose Pérez 6 years ago
parent
commit
e5bf17d019
7 changed files with 307 additions and 19 deletions
  1. +1
    -1
      code/espurna/config/hardware.h
  2. +44
    -13
      code/espurna/config/sensors.h
  3. +6
    -0
      code/espurna/espurna.ino
  4. +10
    -1
      code/espurna/sensor.ino
  5. +1
    -1
      code/espurna/sensors/MHZ19Sensor.h
  6. +3
    -3
      code/espurna/sensors/PMSX003Sensor.h
  7. +242
    -0
      code/espurna/sensors/V9261FSensor.h

+ 1
- 1
code/espurna/config/hardware.h View File

@ -1026,7 +1026,7 @@
#define ALEXA_SUPPORT 0 #define ALEXA_SUPPORT 0
// V9261F // V9261F
#define POWER_PROVIDER POWER_PROVIDER_V9261F
#define V9261F_SUPPORT 1
#define V9261F_PIN 2 #define V9261F_PIN 2
#define V9261F_PIN_INVERSE 1 #define V9261F_PIN_INVERSE 1


+ 44
- 13
code/espurna/config/sensors.h View File

@ -2,33 +2,33 @@
// SENSORS - General data // SENSORS - General data
// ============================================================================= // =============================================================================
#define SENSOR_DEBUG 0 // Debug sensors
#define SENSOR_DEBUG 0 // Debug sensors
#define SENSOR_READ_INTERVAL 6000 // Read data from sensors every 6 seconds
#define SENSOR_REPORT_EVERY 10 // Report every this many readings
#define SENSOR_USE_INDEX 0 // Use the index in topic (i.e. temperature/0)
#define SENSOR_READ_INTERVAL 6000 // Read data from sensors every 6 seconds
#define SENSOR_REPORT_EVERY 10 // Report every this many readings
#define SENSOR_USE_INDEX 0 // Use the index in topic (i.e. temperature/0)
// even if just one sensor (0 for backwards compatibility) // even if just one sensor (0 for backwards compatibility)
#ifndef SENSOR_TEMPERATURE_UNITS #ifndef SENSOR_TEMPERATURE_UNITS
#define SENSOR_TEMPERATURE_UNITS TMP_CELSIUS // Temperature units (TMP_CELSIUS | TMP_FAHRENHEIT)
#define SENSOR_TEMPERATURE_UNITS TMP_CELSIUS // Temperature units (TMP_CELSIUS | TMP_FAHRENHEIT)
#endif #endif
#ifndef SENSOR_TEMPERATURE_CORRECTION #ifndef SENSOR_TEMPERATURE_CORRECTION
#define SENSOR_TEMPERATURE_CORRECTION 0.0 // Offset correction
#define SENSOR_TEMPERATURE_CORRECTION 0.0 // Offset correction
#endif #endif
#ifndef TEMPERATURE_MIN_CHANGE #ifndef TEMPERATURE_MIN_CHANGE
#define TEMPERATURE_MIN_CHANGE 0.0 // Minimum temperature change to report
#define TEMPERATURE_MIN_CHANGE 0.0 // Minimum temperature change to report
#endif #endif
#ifndef HUMIDITY_MIN_CHANGE #ifndef HUMIDITY_MIN_CHANGE
#define HUMIDITY_MIN_CHANGE 0 // Minimum humidity change to report
#define HUMIDITY_MIN_CHANGE 0 // Minimum humidity change to report
#endif #endif
#define HUMIDITY_NORMAL 0
#define HUMIDITY_COMFORTABLE 1
#define HUMIDITY_DRY 2
#define HUMIDITY_WET 3
#define HUMIDITY_NORMAL 0
#define HUMIDITY_COMFORTABLE 1
#define HUMIDITY_DRY 2
#define HUMIDITY_WET 3
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
// Magnitudes // Magnitudes
@ -240,7 +240,7 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#ifndef EMON_ANALOG_SUPPORT #ifndef EMON_ANALOG_SUPPORT
#define EMON_ANALOG_SUPPORT 1 // Do not build support by default
#define EMON_ANALOG_SUPPORT 0 // Do not build support by default
#endif #endif
#if EMON_ANALOG_SUPPORT #if EMON_ANALOG_SUPPORT
@ -331,6 +331,32 @@
#define I2C_SUPPORT 1 #define I2C_SUPPORT 1
#endif #endif
//------------------------------------------------------------------------------
// V9261F based power sensor
// Enable support by passing SI7021_SUPPORT=1 build flag
//------------------------------------------------------------------------------
#ifndef V9261F_SUPPORT
#define V9261F_SUPPORT 0
#endif
#ifndef V9261F_PIN
#define V9261F_PIN 2 // TX pin from the V9261F
#endif
#ifndef V9261F_PIN_INVERSE
#define V9261F_PIN_INVERSE 1 // Signal is inverted
#endif
#define V9261F_SYNC_INTERVAL 600 // Sync signal length (ms)
#define V9261F_BAUDRATE 4800 // UART baudrate
// Default ratios
#define V9261F_CURRENT_FACTOR 79371434.0
#define V9261F_VOLTAGE_FACTOR 4160651.0
#define V9261F_POWER_FACTOR 153699.0
#define V9261F_RPOWER_FACTOR V9261F_CURRENT_FACTOR
// ============================================================================= // =============================================================================
// Sensor helpers configuration // Sensor helpers configuration
// ============================================================================= // =============================================================================
@ -433,3 +459,8 @@
#if SHT3X_I2C_SUPPORT #if SHT3X_I2C_SUPPORT
#include "sensors/SHT3XI2CSensor.h" #include "sensors/SHT3XI2CSensor.h"
#endif #endif
#if V9261F_SUPPORT
#include <SoftwareSerial.h>
#include "sensors/V9261FSensor.h"
#endif

+ 6
- 0
code/espurna/espurna.ino View File

@ -233,9 +233,15 @@ void welcome() {
#if PMSX003_SUPPORT #if PMSX003_SUPPORT
DEBUG_MSG_P(PSTR(" PMSX003")); DEBUG_MSG_P(PSTR(" PMSX003"));
#endif #endif
#if SHT3X_I2C_SUPPORT
DEBUG_MSG_P(PSTR(" SHT3X_I2C"));
#endif
#if SI7021_SUPPORT #if SI7021_SUPPORT
DEBUG_MSG_P(PSTR(" SI7021")); DEBUG_MSG_P(PSTR(" SI7021"));
#endif #endif
#if V9261F_SUPPORT
DEBUG_MSG_P(PSTR(" V9261F"));
#endif
DEBUG_MSG_P(PSTR("\n\n")); DEBUG_MSG_P(PSTR("\n\n"));


+ 10
- 1
code/espurna/sensor.ino View File

@ -353,6 +353,15 @@ void _sensorInit() {
} }
#endif #endif
#if V9261F_SUPPORT
{
V9261FSensor * sensor = new V9261FSensor();
sensor->setRX(V9261F_PIN);
sensor->setInverted(V9261F_PIN_INVERSE);
_sensors.push_back(sensor);
}
#endif
} }
void _sensorConfigure() { void _sensorConfigure() {
@ -424,7 +433,7 @@ void _magnitudesInit() {
if (type == MAGNITUDE_DIGITAL) { if (type == MAGNITUDE_DIGITAL) {
new_magnitude.filter = new MaxFilter(); new_magnitude.filter = new MaxFilter();
} else if (type == MAGNITUDE_EVENTS) { } else if (type == MAGNITUDE_EVENTS) {
new_magnitude.filter = new MovingAverageFilter(SENSOR_REPORT_EVERY);
new_magnitude.filter = new MovingAverageFilter();
} else { } else {
new_magnitude.filter = new MedianFilter(); new_magnitude.filter = new MedianFilter();
} }


+ 1
- 1
code/espurna/sensors/MHZ19Sensor.h View File

@ -193,6 +193,6 @@ class MHZ19Sensor : public BaseSensor {
double _co2 = 0; double _co2 = 0;
unsigned int _pin_rx; unsigned int _pin_rx;
unsigned int _pin_tx; unsigned int _pin_tx;
SoftwareSerial * _serial;
SoftwareSerial * _serial = NULL;
}; };

+ 3
- 3
code/espurna/sensors/PMSX003Sensor.h View File

@ -118,7 +118,7 @@ class PMSX003Sensor : public BaseSensor {
} }
_pms->requestRead(); _pms->requestRead();
} }
// Current value for slot # index // Current value for slot # index
@ -140,8 +140,8 @@ class PMSX003Sensor : public BaseSensor {
unsigned int _pin_rx; unsigned int _pin_rx;
unsigned int _pin_tx; unsigned int _pin_tx;
unsigned long _startTime; unsigned long _startTime;
SoftwareSerial * _serial;
PMS * _pms;
SoftwareSerial * _serial = NULL;
PMS * _pms = NULL;
PMS::DATA _data; PMS::DATA _data;
}; };

+ 242
- 0
code/espurna/sensors/V9261FSensor.h View File

@ -0,0 +1,242 @@
// -----------------------------------------------------------------------------
// V9261F based power monitor
// Copyright (C) 2017 by Xose Pérez <xose dot perez at gmail dot com>
// -----------------------------------------------------------------------------
#pragma once
#include "Arduino.h"
#include "BaseSensor.h"
#include <SoftwareSerial.h>
class V9261FSensor : public BaseSensor {
public:
// ---------------------------------------------------------------------
// Public
// ---------------------------------------------------------------------
V9261FSensor(): BaseSensor() {
_count = 6;
_sensor_id = SENSOR_V9261F_ID;
}
// ---------------------------------------------------------------------
void setRX(unsigned char pin_rx) {
if (_pin_rx == pin_rx) return;
_pin_rx = pin_rx;
_dirty = true;
}
void setInverted(bool inverted) {
if (_inverted == inverted) return;
_inverted = inverted;
_dirty = true;
}
// ---------------------------------------------------------------------
unsigned char getRX() {
return _pin_rx;
}
bool getInverted() {
return _inverted;
}
// ---------------------------------------------------------------------
// Sensor API
// ---------------------------------------------------------------------
// Initialization method, must be idempotent
void begin() {
if (!_dirty) return;
_dirty = false;
if (_serial) delete _serial;
_serial = new SoftwareSerial(_pin_rx, SW_SERIAL_UNUSED_PIN, _inverted, 256);
_serial->begin(V9261F_BAUDRATE);
}
// Descriptive name of the sensor
String description() {
char buffer[28];
snprintf(buffer, sizeof(buffer), "V9261F @ SwSerial(%i,NULL)", _pin_rx);
return String(buffer);
}
// Loop-like method, call it in your main loop
void tick() {
_read();
}
// Type for slot # index
magnitude_t type(unsigned char index) {
_error = SENSOR_ERROR_OK;
if (index == 0) return MAGNITUDE_CURRENT;
if (index == 1) return MAGNITUDE_VOLTAGE;
if (index == 2) return MAGNITUDE_POWER_ACTIVE;
if (index == 3) return MAGNITUDE_POWER_REACTIVE;
if (index == 4) return MAGNITUDE_POWER_APPARENT;
if (index == 5) return MAGNITUDE_POWER_FACTOR;
_error = SENSOR_ERROR_OUT_OF_RANGE;
return MAGNITUDE_NONE;
}
// Current value for slot # index
double value(unsigned char index) {
_error = SENSOR_ERROR_OK;
if (index == 0) return _current;
if (index == 1) return _voltage;
if (index == 2) return _active;
if (index == 3) return _reactive;
if (index == 4) return _apparent;
if (index == 5) return _apparent > 0 ? 100 * _active / _apparent : 100;
_error = SENSOR_ERROR_OUT_OF_RANGE;
return 0;
}
protected:
// ---------------------------------------------------------------------
// Protected
// ---------------------------------------------------------------------
void _read() {
static unsigned char state = 0;
static unsigned long last = 0;
static bool found = false;
static unsigned char index = 0;
if (state == 0) {
while (_serial->available()) {
_serial->flush();
found = true;
last = millis();
}
if (found && (millis() - last > V9261F_SYNC_INTERVAL)) {
_serial->flush();
index = 0;
state = 1;
}
} else if (state == 1) {
while (_serial->available()) {
_serial->read();
if (index++ >= 7) {
_serial->flush();
index = 0;
state = 2;
}
}
} else if (state == 2) {
while (_serial->available()) {
_data[index] = _serial->read();
if (index++ >= 19) {
_serial->flush();
last = millis();
state = 3;
}
}
} else if (state == 3) {
if (_checksum()) {
_active = (double) (
(_data[3]) +
(_data[4] << 8) +
(_data[5] << 16) +
(_data[6] << 24)
) / _ratioP;
_reactive = (double) (
(_data[7]) +
(_data[8] << 8) +
(_data[9] << 16) +
(_data[10] << 24)
) / _ratioR;
_voltage = (double) (
(_data[11]) +
(_data[12] << 8) +
(_data[13] << 16) +
(_data[14] << 24)
) / _ratioV;
_current = (double) (
(_data[15]) +
(_data[16] << 8) +
(_data[17] << 16) +
(_data[18] << 24)
) / _ratioC;
if (_active < 0) _active = 0;
if (_reactive < 0) _reactive = 0;
if (_voltage < 0) _voltage = 0;
if (_current < 0) _current = 0;
_apparent = sqrt(_reactive * _reactive + _active * _active);
}
last = millis();
index = 0;
state = 4;
} else if (state == 4) {
while (_serial->available()) {
_serial->flush();
last = millis();
}
if (millis() - last > V9261F_SYNC_INTERVAL) {
state = 1;
}
}
}
bool _checksum() {
unsigned char checksum = 0;
for (unsigned char i = 0; i < 19; i++) {
checksum = checksum + _data[i];
}
checksum = ~checksum + 0x33;
return checksum == _data[19];
}
// ---------------------------------------------------------------------
unsigned int _pin_rx = V9261F_PIN;
bool _inverted = V9261F_PIN_INVERSE;
SoftwareSerial * _serial = NULL;
double _active = 0;
double _reactive = 0;
double _voltage = 0;
double _current = 0;
double _apparent = 0;
double _ratioP = V9261F_POWER_FACTOR;
double _ratioC = V9261F_CURRENT_FACTOR;
double _ratioV = V9261F_VOLTAGE_FACTOR;
double _ratioR = V9261F_RPOWER_FACTOR;
unsigned char _data[24];
};

Loading…
Cancel
Save