From edf9d465ba31016947eb26d25ec5803cb5de52cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xose=20P=C3=A9rez?= Date: Sat, 16 Dec 2017 22:14:24 +0100 Subject: [PATCH 1/9] Improve ADS1115 speed to 1450 SPS, keep separate pivot for each channel --- code/espurna/config/sensors.h | 2 +- code/espurna/sensors/EmonADC121Sensor.h | 10 +++--- code/espurna/sensors/EmonADS1115Sensor.h | 42 ++++++++++++------------ code/espurna/sensors/EmonAnalogSensor.h | 5 +-- code/espurna/sensors/EmonSensor.h | 14 ++++---- 5 files changed, 36 insertions(+), 37 deletions(-) diff --git a/code/espurna/config/sensors.h b/code/espurna/config/sensors.h index b9de94a4..e690ed13 100644 --- a/code/espurna/config/sensors.h +++ b/code/espurna/config/sensors.h @@ -143,7 +143,7 @@ //-------------------------------------------------------------------------------- #define EMON_MAX_SAMPLES 1000 // Max number of samples to get -#define EMON_MAX_TIME 500 // Max time in ms to sample +#define EMON_MAX_TIME 250 // Max time in ms to sample #define EMON_FILTER_SPEED 512 // Mobile average filter speed #define EMON_MAINS_VOLTAGE 230 // Mains voltage diff --git a/code/espurna/sensors/EmonADC121Sensor.h b/code/espurna/sensors/EmonADC121Sensor.h index 1395d6cf..2a890474 100644 --- a/code/espurna/sensors/EmonADC121Sensor.h +++ b/code/espurna/sensors/EmonADC121Sensor.h @@ -88,7 +88,7 @@ class EmonADC121Sensor : public EmonSensor { static unsigned long energy_delta = 0; if ((last == 0) || (millis() - last > 1000)) { - current = read(_address); + current = read(0, _pivot); energy_delta = current * _voltage * (millis() - last) / 1000; _energy += energy_delta; last = millis(); @@ -113,17 +113,17 @@ class EmonADC121Sensor : public EmonSensor { #if I2C_USE_BRZO uint8_t buffer[2]; buffer[0] = ADC121_REG_RESULT; - brzo_i2c_start_transaction(channel, I2C_SCL_FREQUENCY); + brzo_i2c_start_transaction(_address, I2C_SCL_FREQUENCY); brzo_i2c_write(buffer, 1, false); brzo_i2c_read(buffer, 2, false); brzo_i2c_end_transaction(); value = (buffer[0] & 0x0F) << 8; value |= buffer[1]; #else - Wire.beginTransmission(channel); + Wire.beginTransmission(_address); Wire.write(ADC121_REG_RESULT); Wire.endTransmission(); - Wire.requestFrom(channel, (unsigned char) 2); + Wire.requestFrom(_address, (unsigned char) 2); value = (Wire.read() & 0x0F) << 8; value = value + Wire.read(); #endif @@ -134,6 +134,6 @@ class EmonADC121Sensor : public EmonSensor { unsigned char _address; unsigned long _energy = 0; - + double _pivot = 0; }; diff --git a/code/espurna/sensors/EmonADS1115Sensor.h b/code/espurna/sensors/EmonADS1115Sensor.h index 889b0bac..7446e329 100644 --- a/code/espurna/sensors/EmonADS1115Sensor.h +++ b/code/espurna/sensors/EmonADS1115Sensor.h @@ -84,7 +84,7 @@ #define ADS1015_REG_CONFIG_CQUE_NONE (0x0003) // Disable the comparator and put ALERT/RDY in high state (default) */ -#define EMON_ADS1115_CHANNELS 4 +#define EMON_ADS1115_CHANNELS 4 #define EMON_ADS1115_MAGNITUDES_PER_PORT 2 class EmonADS1115Sensor : public EmonSensor { @@ -106,13 +106,16 @@ class EmonADS1115Sensor : public EmonSensor { // Initialize _ads = new ADS1115(_address); _ads->initialize(); - _ads->setMode(ADS1115_MODE_SINGLESHOT); + _ads->setMode(ADS1115_MODE_CONTINUOUS); _ads->setRate(ADS1115_RATE_860); _ads->setGain(ADS1115_PGA_4P096); - _ads->setConversionReadyPinMode(); // warmup - read(_address); + for (unsigned char port=0; port<_ports; port++) { + unsigned char channel = getChannel(port); + _ads->setMultiplexer(channel + 4); + read(channel, _pivot[channel]); + } } @@ -126,8 +129,8 @@ class EmonADS1115Sensor : public EmonSensor { // Descriptive name of the slot # index String slot(unsigned char index) { char buffer[35]; - unsigned char port = getChannel(index / EMON_ADS1115_MAGNITUDES_PER_PORT); - snprintf(buffer, sizeof(buffer), "EMON @ ADS1115 (A%d) @ I2C (0x%02X)", port, _address); + unsigned char channel = getChannel(index % _ports); + snprintf(buffer, sizeof(buffer), "EMON @ ADS1115 (A%d) @ I2C (0x%02X)", channel, _address); return String(buffer); } @@ -135,8 +138,7 @@ class EmonADS1115Sensor : public EmonSensor { magnitude_t type(unsigned char index) { if (index < _count) { _error = SENSOR_ERROR_OK; - unsigned char port = getChannel(index / EMON_ADS1115_MAGNITUDES_PER_PORT); - unsigned char magnitude = index % EMON_ADS1115_MAGNITUDES_PER_PORT; + unsigned char magnitude = index / _ports; if (magnitude == 0) return MAGNITUDE_CURRENT; if (magnitude == 1) return MAGNITUDE_POWER_APPARENT; //if (magnitude == 2) return MAGNITUDE_ENERGY; @@ -148,9 +150,10 @@ class EmonADS1115Sensor : public EmonSensor { void pre() { //static unsigned long last = 0; - for (unsigned char index=0; index<_ports; index++) { - unsigned char port = getChannel(index); - _current[port] = read(port); + for (unsigned char port=0; port<_ports; port++) { + unsigned char channel = getChannel(port); + _ads->setMultiplexer(channel + 4); + _current[port] = read(channel, _pivot[channel]); //if (last > 0) { // _delta[port] = _current[port] * _voltage * (millis() - last) / 1000; //} @@ -164,8 +167,8 @@ class EmonADS1115Sensor : public EmonSensor { if (index < _count) { _error = SENSOR_ERROR_OK; - unsigned char port = getChannel(index / EMON_ADS1115_MAGNITUDES_PER_PORT); - unsigned char magnitude = index % EMON_ADS1115_MAGNITUDES_PER_PORT; + unsigned char port = index % _ports; + unsigned char magnitude = index / _ports; if (magnitude == 0) return _current[port]; if (magnitude == 1) return _current[port] * _voltage; //if (magnitude == 2) return _energy[port]; @@ -193,11 +196,7 @@ class EmonADS1115Sensor : public EmonSensor { } unsigned int readADC(unsigned char channel) { - if (channel < EMON_ADS1115_CHANNELS) { - _ads->setMultiplexer(channel + 4); - return _ads->getConversion(true); - } - return 0; + return _ads->getConversion(); } /* @@ -272,9 +271,10 @@ class EmonADS1115Sensor : public EmonSensor { unsigned char _address; unsigned char _mask; unsigned char _ports; - double _current[EMON_ADS1115_CHANNELS] = {0, 0, 0, 0}; - //unsigned long _energy[EMON_ADS1115_CHANNELS] = {0, 0, 0, 0}; - //unsigned long _delta[EMON_ADS1115_CHANNELS] = {0, 0, 0, 0}; + double _pivot[EMON_ADS1115_CHANNELS] = {0}; + double _current[EMON_ADS1115_CHANNELS] = {0}; + //unsigned long _energy[EMON_ADS1115_CHANNELS] = {0}; + //unsigned long _delta[EMON_ADS1115_CHANNELS] = {0}; }; diff --git a/code/espurna/sensors/EmonAnalogSensor.h b/code/espurna/sensors/EmonAnalogSensor.h index 3e6e977a..0a7db4de 100644 --- a/code/espurna/sensors/EmonAnalogSensor.h +++ b/code/espurna/sensors/EmonAnalogSensor.h @@ -60,7 +60,7 @@ class EmonAnalogSensor : public EmonSensor { static unsigned long energy_delta = 0; if ((last == 0) || (millis() - last > 1000)) { - current = read(_gpio); + current = read(0, _pivot); energy_delta = current * _voltage * (millis() - last) / 1000; _energy += energy_delta; last = millis(); @@ -79,11 +79,12 @@ class EmonAnalogSensor : public EmonSensor { protected: unsigned int readADC(unsigned char channel) { - return analogRead(channel); + return analogRead(_gpio); } unsigned char _gpio; unsigned long _energy = 0; + double _pivot = 0; }; diff --git a/code/espurna/sensors/EmonSensor.h b/code/espurna/sensors/EmonSensor.h index 29912b0c..acf8afde 100644 --- a/code/espurna/sensors/EmonSensor.h +++ b/code/espurna/sensors/EmonSensor.h @@ -18,7 +18,6 @@ class EmonSensor : public BaseSensor { // Cache _voltage = voltage; _adc_counts = 1 << bits; - _pivot = _adc_counts >> 1; // Calculate factor _current_factor = ratio * ref / _adc_counts; @@ -52,7 +51,7 @@ class EmonSensor : public BaseSensor { } } - double read(unsigned char channel) { + double read(unsigned char channel, double &pivot) { int sample; int max = 0; @@ -69,8 +68,8 @@ class EmonSensor : public BaseSensor { if (sample < min) min = sample; // Digital low pass filter extracts the VDC offset - _pivot = (_pivot + (sample - _pivot) / EMON_FILTER_SPEED); - filtered = sample - _pivot; + pivot = (pivot + (sample - pivot) / EMON_FILTER_SPEED); + filtered = sample - pivot; // Root-mean-square method sum += (filtered * filtered); @@ -79,8 +78,8 @@ class EmonSensor : public BaseSensor { time_span = millis() - time_span; // Quick fix - if (_pivot < min || max < _pivot) { - _pivot = (max + min) / 2.0; + if (pivot < min || max < pivot) { + pivot = (max + min) / 2.0; } // Calculate current @@ -95,7 +94,7 @@ class EmonSensor : public BaseSensor { Serial.print("[EMON] Sample frequency (Hz): "); Serial.println(1000 * _samples / time_span); Serial.print("[EMON] Max value: "); Serial.println(max); Serial.print("[EMON] Min value: "); Serial.println(min); - Serial.print("[EMON] Midpoint value: "); Serial.println(_pivot); + Serial.print("[EMON] Midpoint value: "); Serial.println(pivot); Serial.print("[EMON] RMS value: "); Serial.println(rms); Serial.print("[EMON] Current: "); Serial.println(current); #endif @@ -114,7 +113,6 @@ class EmonSensor : public BaseSensor { unsigned long _adc_counts; unsigned int _multiplier = 1; double _current_factor; - double _pivot; unsigned long _samples = EMON_MAX_SAMPLES; From 8b56ab86523f445224924eb7c8df9bb04379b3fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xose=20P=C3=A9rez?= Date: Sun, 17 Dec 2017 00:56:45 +0100 Subject: [PATCH 2/9] Some renaming --- code/espurna/config/prototypes.h | 2 +- code/espurna/config/sensors.h | 22 +- code/espurna/sensor.ino | 6 +- code/espurna/sensors/EmonADS1115Sensor.h | 280 ------------------- code/espurna/sensors/EmonADS1X15Sensor.h | 326 +++++++++++++++++++++++ 5 files changed, 342 insertions(+), 294 deletions(-) delete mode 100644 code/espurna/sensors/EmonADS1115Sensor.h create mode 100644 code/espurna/sensors/EmonADS1X15Sensor.h diff --git a/code/espurna/config/prototypes.h b/code/espurna/config/prototypes.h index 6d76cd7a..2d62b486 100644 --- a/code/espurna/config/prototypes.h +++ b/code/espurna/config/prototypes.h @@ -78,7 +78,7 @@ template bool idbSend(const char * topic, unsigned char id, T payloa #if DS18B20_SUPPORT #include #endif -#if EMON_ADS1115_SUPPORT +#if EMON_ADS1X15_SUPPORT & EMON_ADSX115_USE_I2CDEVLIB #include #endif diff --git a/code/espurna/config/sensors.h b/code/espurna/config/sensors.h index e690ed13..7a593a84 100644 --- a/code/espurna/config/sensors.h +++ b/code/espurna/config/sensors.h @@ -181,21 +181,23 @@ #define EMON_ADC121_REFERENCE_VOLTAGE 3.3 // Reference voltage of the ADC //-------------------------------------------------------------------------------- -// Energy Monitor based on ADS1115 -// Enable support by passing EMON_ADS1115_SUPPORT=1 build flag +// Energy Monitor based on ADS1X15 +// Enable support by passing EMON_ADS1X15_SUPPORT=1 build flag //-------------------------------------------------------------------------------- -#ifndef EMON_ADS1115_SUPPORT -#define EMON_ADS1115_SUPPORT 1 // Do not build support by default +#ifndef EMON_ADS1X15_SUPPORT +#define EMON_ADS1X15_SUPPORT 1 // Do not build support by default #endif -#define EMON_ADS1115_PORT_MASK 0x08 // A0=1 A1=2 A2=4 A4=8 -#define EMON_ADS1115_I2C_ADDRESS 0x48 // I2C address of the ADS1115 +#define EMON_ADSX115_USE_I2CDEVLIB 1 // Use I2CDevLib -#define EMON_ADS1115_CURRENT_RATIO 30 // Current ratio in the clamp (30V/1A) -#define EMON_ADS1115_ADC_BITS 16 // ADC depth -#define EMON_ADS1115_GAIN ADS1115_PGA_4P096 -#define EMON_ADS1115_REFERENCE_VOLTAGE 8.192 // Double the gain for peak-to-peak +#define EMON_ADS1X15_ADS1115 1 // 0 for ADS10115, 1 for ADS1115 +#define EMON_ADS1X15_PORT_MASK 0x08 // A0=1 A1=2 A2=4 A4=8 +#define EMON_ADS1X15_I2C_ADDRESS 0x48 // I2C address of the ADS1115 + +#define EMON_ADS1X15_CURRENT_RATIO 30 // Current ratio in the clamp (30V/1A) +#define EMON_ADS1X15_ADC_BITS 16 // ADC depth +#define EMON_ADS1X15_REFERENCE_VOLTAGE 8.192 // Double the gain for peak-to-peak //-------------------------------------------------------------------------------- // Internal power montior diff --git a/code/espurna/sensor.ino b/code/espurna/sensor.ino index 30cf144b..79a101b0 100644 --- a/code/espurna/sensor.ino +++ b/code/espurna/sensor.ino @@ -248,9 +248,9 @@ void sensorInit() { sensorRegister(new EmonADC121Sensor(EMON_ADC121_I2C_ADDRESS, EMON_MAINS_VOLTAGE, EMON_ADC121_ADC_BITS, EMON_ADC121_REFERENCE_VOLTAGE, EMON_ADC121_CURRENT_RATIO)); #endif - #if EMON_ADS1115_SUPPORT - #include "sensors/EmonADS1115Sensor.h" - sensorRegister(new EmonADS1115Sensor(EMON_ADS1115_I2C_ADDRESS, EMON_ADS1115_PORT_MASK, EMON_MAINS_VOLTAGE, EMON_ADS1115_ADC_BITS, EMON_ADS1115_REFERENCE_VOLTAGE, EMON_ADS1115_CURRENT_RATIO)); + #if EMON_ADS1X15_SUPPORT + #include "sensors/EmonADS1X15Sensor.h" + sensorRegister(new EmonADS1X15Sensor(EMON_ADS1X15_I2C_ADDRESS, EMON_ADS1X15_ADS1115, EMON_ADS1X15_PORT_MASK, EMON_MAINS_VOLTAGE, EMON_ADS1X15_ADC_BITS, EMON_ADS1X15_REFERENCE_VOLTAGE, EMON_ADS1X15_CURRENT_RATIO)); #endif #if COUNTER_SUPPORT diff --git a/code/espurna/sensors/EmonADS1115Sensor.h b/code/espurna/sensors/EmonADS1115Sensor.h deleted file mode 100644 index 7446e329..00000000 --- a/code/espurna/sensors/EmonADS1115Sensor.h +++ /dev/null @@ -1,280 +0,0 @@ -// ----------------------------------------------------------------------------- -// Energy monitor sensor -// ----------------------------------------------------------------------------- - -#pragma once - -#include "Arduino.h" -#include "BaseSensor.h" -#include "EmonSensor.h" - -#include - -/* -#if I2C_USE_BRZO -#include -#else -#include -#endif - -#define ADS1015_CONVERSIONDELAY (1) -#define ADS1115_CONVERSIONDELAY (8) - -#define ADS1015_BIT_SHIFT (4) -#define ADS1115_BIT_SHIFT (0) - -#define ADS1015_REG_POINTER_MASK (0x03) -#define ADS1015_REG_POINTER_CONVERT (0x00) -#define ADS1015_REG_POINTER_CONFIG (0x01) -#define ADS1015_REG_POINTER_LOWTHRESH (0x02) -#define ADS1015_REG_POINTER_HITHRESH (0x03) - -#define ADS1015_REG_CONFIG_OS_MASK (0x8000) -#define ADS1015_REG_CONFIG_OS_SINGLE (0x8000) // Write: Set to start a single-conversion -#define ADS1015_REG_CONFIG_OS_BUSY (0x0000) // Read: Bit = 0 when conversion is in progress -#define ADS1015_REG_CONFIG_OS_NOTBUSY (0x8000) // Read: Bit = 1 when device is not performing a conversion - -#define ADS1015_REG_CONFIG_MUX_MASK (0x7000) -#define ADS1015_REG_CONFIG_MUX_DIFF_0_1 (0x0000) // Differential P = AIN0, N = AIN1 (default) -#define ADS1015_REG_CONFIG_MUX_DIFF_0_3 (0x1000) // Differential P = AIN0, N = AIN3 -#define ADS1015_REG_CONFIG_MUX_DIFF_1_3 (0x2000) // Differential P = AIN1, N = AIN3 -#define ADS1015_REG_CONFIG_MUX_DIFF_2_3 (0x3000) // Differential P = AIN2, N = AIN3 -#define ADS1015_REG_CONFIG_MUX_SINGLE_0 (0x4000) // Single-ended AIN0 -#define ADS1015_REG_CONFIG_MUX_SINGLE_1 (0x5000) // Single-ended AIN1 -#define ADS1015_REG_CONFIG_MUX_SINGLE_2 (0x6000) // Single-ended AIN2 -#define ADS1015_REG_CONFIG_MUX_SINGLE_3 (0x7000) // Single-ended AIN3 - -#define ADS1015_REG_CONFIG_PGA_MASK (0x0E00) -#define ADS1015_REG_CONFIG_PGA_6_144V (0x0000) // +/-6.144V range = Gain 2/3 -#define ADS1015_REG_CONFIG_PGA_4_096V (0x0200) // +/-4.096V range = Gain 1 -#define ADS1015_REG_CONFIG_PGA_2_048V (0x0400) // +/-2.048V range = Gain 2 (default) -#define ADS1015_REG_CONFIG_PGA_1_024V (0x0600) // +/-1.024V range = Gain 4 -#define ADS1015_REG_CONFIG_PGA_0_512V (0x0800) // +/-0.512V range = Gain 8 -#define ADS1015_REG_CONFIG_PGA_0_256V (0x0A00) // +/-0.256V range = Gain 16 - -#define ADS1015_REG_CONFIG_MODE_MASK (0x0100) -#define ADS1015_REG_CONFIG_MODE_CONTIN (0x0000) // Continuous conversion mode -#define ADS1015_REG_CONFIG_MODE_SINGLE (0x0100) // Power-down single-shot mode (default) - -#define ADS1015_REG_CONFIG_DR_MASK (0x00E0) -#define ADS1015_REG_CONFIG_DR_128SPS (0x0000) // 128 samples per second -#define ADS1015_REG_CONFIG_DR_250SPS (0x0020) // 250 samples per second -#define ADS1015_REG_CONFIG_DR_490SPS (0x0040) // 490 samples per second -#define ADS1015_REG_CONFIG_DR_920SPS (0x0060) // 920 samples per second -#define ADS1015_REG_CONFIG_DR_1600SPS (0x0080) // 1600 samples per second (default) -#define ADS1015_REG_CONFIG_DR_2400SPS (0x00A0) // 2400 samples per second -#define ADS1015_REG_CONFIG_DR_3300SPS (0x00C0) // 3300 samples per second - -#define ADS1015_REG_CONFIG_CMODE_MASK (0x0010) -#define ADS1015_REG_CONFIG_CMODE_TRAD (0x0000) // Traditional comparator with hysteresis (default) -#define ADS1015_REG_CONFIG_CMODE_WINDOW (0x0010) // Window comparator - -#define ADS1015_REG_CONFIG_CPOL_MASK (0x0008) -#define ADS1015_REG_CONFIG_CPOL_ACTVLOW (0x0000) // ALERT/RDY pin is low when active (default) -#define ADS1015_REG_CONFIG_CPOL_ACTVHI (0x0008) // ALERT/RDY pin is high when active - -#define ADS1015_REG_CONFIG_CLAT_MASK (0x0004) // Determines if ALERT/RDY pin latches once asserted -#define ADS1015_REG_CONFIG_CLAT_NONLAT (0x0000) // Non-latching comparator (default) -#define ADS1015_REG_CONFIG_CLAT_LATCH (0x0004) // Latching comparator - -#define ADS1015_REG_CONFIG_CQUE_MASK (0x0003) -#define ADS1015_REG_CONFIG_CQUE_1CONV (0x0000) // Assert ALERT/RDY after one conversions -#define ADS1015_REG_CONFIG_CQUE_2CONV (0x0001) // Assert ALERT/RDY after two conversions -#define ADS1015_REG_CONFIG_CQUE_4CONV (0x0002) // Assert ALERT/RDY after four conversions -#define ADS1015_REG_CONFIG_CQUE_NONE (0x0003) // Disable the comparator and put ALERT/RDY in high state (default) -*/ - -#define EMON_ADS1115_CHANNELS 4 -#define EMON_ADS1115_MAGNITUDES_PER_PORT 2 - -class EmonADS1115Sensor : public EmonSensor { - - public: - - EmonADS1115Sensor(unsigned char address, unsigned char mask, double voltage, unsigned char bits, double ref, double ratio): EmonSensor(voltage, bits, ref, ratio) { - - // Cache - _address = address; - _mask = mask; - _ports = 0; - while (mask) { - if (mask & 0x01) ++_ports; - mask = mask >> 1; - } - _count = _ports * EMON_ADS1115_MAGNITUDES_PER_PORT; - - // Initialize - _ads = new ADS1115(_address); - _ads->initialize(); - _ads->setMode(ADS1115_MODE_CONTINUOUS); - _ads->setRate(ADS1115_RATE_860); - _ads->setGain(ADS1115_PGA_4P096); - - // warmup - for (unsigned char port=0; port<_ports; port++) { - unsigned char channel = getChannel(port); - _ads->setMultiplexer(channel + 4); - read(channel, _pivot[channel]); - } - - } - - // Descriptive name of the sensor - String name() { - char buffer[30]; - snprintf(buffer, sizeof(buffer), "EMON @ ADS1115 @ I2C (0x%02X)", _address); - return String(buffer); - } - - // Descriptive name of the slot # index - String slot(unsigned char index) { - char buffer[35]; - unsigned char channel = getChannel(index % _ports); - snprintf(buffer, sizeof(buffer), "EMON @ ADS1115 (A%d) @ I2C (0x%02X)", channel, _address); - return String(buffer); - } - - // Type for slot # index - magnitude_t type(unsigned char index) { - if (index < _count) { - _error = SENSOR_ERROR_OK; - unsigned char magnitude = index / _ports; - if (magnitude == 0) return MAGNITUDE_CURRENT; - if (magnitude == 1) return MAGNITUDE_POWER_APPARENT; - //if (magnitude == 2) return MAGNITUDE_ENERGY; - //if (magnitude == 3) return MAGNITUDE_ENERGY_DELTA; - } - _error = SENSOR_ERROR_OUT_OF_RANGE; - return MAGNITUDE_NONE; - } - - void pre() { - //static unsigned long last = 0; - for (unsigned char port=0; port<_ports; port++) { - unsigned char channel = getChannel(port); - _ads->setMultiplexer(channel + 4); - _current[port] = read(channel, _pivot[channel]); - //if (last > 0) { - // _delta[port] = _current[port] * _voltage * (millis() - last) / 1000; - //} - //_energy[port] += _delta[port]; - } - //last = millis(); - } - - // Current value for slot # index - double value(unsigned char index) { - - if (index < _count) { - _error = SENSOR_ERROR_OK; - unsigned char port = index % _ports; - unsigned char magnitude = index / _ports; - if (magnitude == 0) return _current[port]; - if (magnitude == 1) return _current[port] * _voltage; - //if (magnitude == 2) return _energy[port]; - //if (magnitude == 3) return _delta[port]; - } - - _error = SENSOR_ERROR_OUT_OF_RANGE; - return 0; - - } - - protected: - - unsigned char getChannel(unsigned char port) { - unsigned char count = 0; - unsigned char bit = 1; - for (unsigned char channel=0; channelgetConversion(); - } - - /* - unsigned int readADC(unsigned char channel) { - - if (channel > 3) return 0; - channel = 3; - unsigned int value; - - // Start with default values - uint16_t config = 0; - - config |= ADS1015_REG_CONFIG_CQUE_NONE; // Disable the comparator (default val) - config |= ADS1015_REG_CONFIG_CLAT_NONLAT; // Non-latching (default val) - config |= ADS1015_REG_CONFIG_CPOL_ACTVLOW; // Alert/Rdy active low (default val) - config |= ADS1015_REG_CONFIG_CMODE_TRAD; // Traditional comparator (default val) - config |= ADS1015_REG_CONFIG_DR_1600SPS; // 1600 samples per second (default) - config |= ADS1015_REG_CONFIG_MODE_SINGLE; // Single-shot mode (default) - config |= ADS1015_REG_CONFIG_OS_SINGLE; // Set 'start single-conversion' bit - config |= EMON_ADS1115_GAIN; // Set PGA/voltage range - config |= ((channel + 4) << 12); // Set single-ended input channel - - Serial.println(config); - - // Write config register to the ADC - #if I2C_USE_BRZO - uint8_t buffer[3]; - buffer[0] = ADS1015_REG_POINTER_CONFIG; - buffer[1] = config >> 8; - buffer[2] = config & 0xFF; - brzo_i2c_start_transaction(_address, I2C_SCL_FREQUENCY); - brzo_i2c_write(buffer, 3, false); - //brzo_i2c_end_transaction(); - #else - Wire.beginTransmission(_address); - Wire.write((uint8_t) ADS1015_REG_POINTER_CONFIG); - Wire.write((uint8_t) (config >> 8)); - Wire.write((uint8_t) (config & 0xFF)); - Wire.endTransmission(); - #endif - - // Wait for the conversion to complete - unsigned long start = millis(); - while (millis() - start < ADS1115_CONVERSIONDELAY) delay(1); - - // Read the conversion results - // Shift 12-bit results right 4 bits for the ADS1015 - #if I2C_USE_BRZO - buffer[0] = ADS1015_REG_POINTER_CONVERT; - //brzo_i2c_start_transaction(_address, I2C_SCL_FREQUENCY); - brzo_i2c_write(buffer, 1, false); - brzo_i2c_read(buffer, 2, false); - brzo_i2c_end_transaction(); - value = (buffer[0] & 0x0F) << 8; - value |= buffer[1]; - #else - Wire.beginTransmission(_address); - Wire.write(ADS1015_REG_POINTER_CONVERT); - Wire.endTransmission(); - Wire.requestFrom(_address, (unsigned char) 2); - value = Wire.read() << 8; - value |= Wire.read(); - #endif - - return value; - - } - */ - - ADS1115 * _ads; - - unsigned char _address; - unsigned char _mask; - unsigned char _ports; - double _pivot[EMON_ADS1115_CHANNELS] = {0}; - double _current[EMON_ADS1115_CHANNELS] = {0}; - //unsigned long _energy[EMON_ADS1115_CHANNELS] = {0}; - //unsigned long _delta[EMON_ADS1115_CHANNELS] = {0}; - - -}; diff --git a/code/espurna/sensors/EmonADS1X15Sensor.h b/code/espurna/sensors/EmonADS1X15Sensor.h new file mode 100644 index 00000000..b5e3309f --- /dev/null +++ b/code/espurna/sensors/EmonADS1X15Sensor.h @@ -0,0 +1,326 @@ +// ----------------------------------------------------------------------------- +// Energy monitor sensor +// ----------------------------------------------------------------------------- + +#pragma once + +#include "Arduino.h" +#include "BaseSensor.h" +#include "EmonSensor.h" + +#if EMON_ADSX115_USE_I2CDEVLIB + #include +#else + #if I2C_USE_BRZO + #include + #else + #include + #endif +#endif + +#define ADS1015_CONVERSIONDELAY (1) +#define ADS1115_CONVERSIONDELAY (8) + +#define ADS1015_BIT_SHIFT (4) +#define ADS1115_BIT_SHIFT (0) + +#define ADS1X15_REG_POINTER_MASK (0x03) +#define ADS1X15_REG_POINTER_CONVERT (0x00) +#define ADS1X15_REG_POINTER_CONFIG (0x01) +#define ADS1X15_REG_POINTER_LOWTHRESH (0x02) +#define ADS1X15_REG_POINTER_HITHRESH (0x03) + +#define ADS1X15_REG_CONFIG_OS_MASK (0x8000) +#define ADS1X15_REG_CONFIG_OS_SINGLE (0x8000) // Write: Set to start a single-conversion +#define ADS1X15_REG_CONFIG_OS_BUSY (0x0000) // Read: Bit = 0 when conversion is in progress +#define ADS1X15_REG_CONFIG_OS_NOTBUSY (0x8000) // Read: Bit = 1 when device is not performing a conversion + +#define ADS1X15_REG_CONFIG_MUX_MASK (0x7000) +#define ADS1X15_REG_CONFIG_MUX_DIFF_0_1 (0x0000) // Differential P = AIN0, N = AIN1 (default) +#define ADS1X15_REG_CONFIG_MUX_DIFF_0_3 (0x1000) // Differential P = AIN0, N = AIN3 +#define ADS1X15_REG_CONFIG_MUX_DIFF_1_3 (0x2000) // Differential P = AIN1, N = AIN3 +#define ADS1X15_REG_CONFIG_MUX_DIFF_2_3 (0x3000) // Differential P = AIN2, N = AIN3 +#define ADS1X15_REG_CONFIG_MUX_SINGLE_0 (0x4000) // Single-ended AIN0 +#define ADS1X15_REG_CONFIG_MUX_SINGLE_1 (0x5000) // Single-ended AIN1 +#define ADS1X15_REG_CONFIG_MUX_SINGLE_2 (0x6000) // Single-ended AIN2 +#define ADS1X15_REG_CONFIG_MUX_SINGLE_3 (0x7000) // Single-ended AIN3 + +#define ADS1X15_REG_CONFIG_PGA_MASK (0x0E00) +#define ADS1X15_REG_CONFIG_PGA_6_144V (0x0000) // +/-6.144V range = Gain 2/3 +#define ADS1X15_REG_CONFIG_PGA_4_096V (0x0200) // +/-4.096V range = Gain 1 +#define ADS1X15_REG_CONFIG_PGA_2_048V (0x0400) // +/-2.048V range = Gain 2 (default) +#define ADS1X15_REG_CONFIG_PGA_1_024V (0x0600) // +/-1.024V range = Gain 4 +#define ADS1X15_REG_CONFIG_PGA_0_512V (0x0800) // +/-0.512V range = Gain 8 +#define ADS1X15_REG_CONFIG_PGA_0_256V (0x0A00) // +/-0.256V range = Gain 16 + +#define ADS1X15_REG_CONFIG_MODE_MASK (0x0100) +#define ADS1X15_REG_CONFIG_MODE_CONTIN (0x0000) // Continuous conversion mode +#define ADS1X15_REG_CONFIG_MODE_SINGLE (0x0100) // Power-down single-shot mode (default) + +#define ADS1X15_REG_CONFIG_DR_MASK (0x00E0) +#define ADS1015_REG_CONFIG_DR_128SPS (0x0000) // 128 samples per second +#define ADS1015_REG_CONFIG_DR_250SPS (0x0020) // 250 samples per second +#define ADS1015_REG_CONFIG_DR_490SPS (0x0040) // 490 samples per second +#define ADS1015_REG_CONFIG_DR_920SPS (0x0060) // 920 samples per second +#define ADS1015_REG_CONFIG_DR_1600SPS (0x0080) // 1600 samples per second (default) +#define ADS1015_REG_CONFIG_DR_2400SPS (0x00A0) // 2400 samples per second +#define ADS1015_REG_CONFIG_DR_3300SPS (0x00C0) // 3300 samples per second +#define ADS1115_REG_CONFIG_DR_8SPS (0x0000) // 8 samples per second +#define ADS1115_REG_CONFIG_DR_16SPS (0x0020) // 16 samples per second +#define ADS1115_REG_CONFIG_DR_32SPS (0x0040) // 32 samples per second +#define ADS1115_REG_CONFIG_DR_64SPS (0x0060) // 64 samples per second +#define ADS1115_REG_CONFIG_DR_128SPS (0x0080) // 128 samples per second (default) +#define ADS1115_REG_CONFIG_DR_250SPS (0x00A0) // 250 samples per second +#define ADS1115_REG_CONFIG_DR_475SPS (0x00C0) // 475 samples per second +#define ADS1115_REG_CONFIG_DR_860SPS (0x00E0) // 860 samples per second + +#define ADS1X15_REG_CONFIG_CMODE_MASK (0x0010) +#define ADS1X15_REG_CONFIG_CMODE_TRAD (0x0000) // Traditional comparator with hysteresis (default) +#define ADS1X15_REG_CONFIG_CMODE_WINDOW (0x0010) // Window comparator + +#define ADS1X15_REG_CONFIG_CPOL_MASK (0x0008) +#define ADS1X15_REG_CONFIG_CPOL_ACTVLOW (0x0000) // ALERT/RDY pin is low when active (default) +#define ADS1X15_REG_CONFIG_CPOL_ACTVHI (0x0008) // ALERT/RDY pin is high when active + +#define ADS1X15_REG_CONFIG_CLAT_MASK (0x0004) // Determines if ALERT/RDY pin latches once asserted +#define ADS1X15_REG_CONFIG_CLAT_NONLAT (0x0000) // Non-latching comparator (default) +#define ADS1X15_REG_CONFIG_CLAT_LATCH (0x0004) // Latching comparator + +#define ADS1X15_REG_CONFIG_CQUE_MASK (0x0003) +#define ADS1X15_REG_CONFIG_CQUE_1CONV (0x0000) // Assert ALERT/RDY after one conversions +#define ADS1X15_REG_CONFIG_CQUE_2CONV (0x0001) // Assert ALERT/RDY after two conversions +#define ADS1X15_REG_CONFIG_CQUE_4CONV (0x0002) // Assert ALERT/RDY after four conversions +#define ADS1X15_REG_CONFIG_CQUE_NONE (0x0003) // Disable the comparator and put ALERT/RDY in high state (default) +#define ADS1X15_CHANNELS 4 +#define EMON_ADS1X15_MAGNITUDES_PER_PORT 2 + +class EmonADS1X15Sensor : public EmonSensor { + + public: + + EmonADS1X15Sensor(unsigned char address, bool is_ads1115, unsigned char mask, double voltage, unsigned char bits, double ref, double ratio): EmonSensor(voltage, bits, ref, ratio) { + + // Cache + _is_ads1115 = is_ads1115; + _address = address; + _mask = mask; + _ports = 0; + while (mask) { + if (mask & 0x01) ++_ports; + mask = mask >> 1; + } + _count = _ports * EMON_ADS1X15_MAGNITUDES_PER_PORT; + + // initialize + init(); + + // warmup + warmup(); + + } + + // Descriptive name of the sensor + String name() { + char buffer[30]; + snprintf(buffer, sizeof(buffer), "EMON @ ADS1%d15 @ I2C (0x%02X)", _is_ads1115 ? 1 : 0, _address); + return String(buffer); + } + + // Descriptive name of the slot # index + String slot(unsigned char index) { + char buffer[35]; + unsigned char channel = getChannel(index % _ports); + snprintf(buffer, sizeof(buffer), "EMON @ ADS1%d15 (A%d) @ I2C (0x%02X)", _is_ads1115 ? 1 : 0, channel, _address); + return String(buffer); + } + + // Type for slot # index + magnitude_t type(unsigned char index) { + if (index < _count) { + _error = SENSOR_ERROR_OK; + unsigned char magnitude = index / _ports; + if (magnitude == 0) return MAGNITUDE_CURRENT; + if (magnitude == 1) return MAGNITUDE_POWER_APPARENT; + //if (magnitude == 2) return MAGNITUDE_ENERGY; + //if (magnitude == 3) return MAGNITUDE_ENERGY_DELTA; + } + _error = SENSOR_ERROR_OUT_OF_RANGE; + return MAGNITUDE_NONE; + } + + void pre() { + //static unsigned long last = 0; + for (unsigned char port=0; port<_ports; port++) { + unsigned char channel = getChannel(port); + _current[port] = getCurrent(channel); + //if (last > 0) { + // _delta[port] = _current[port] * _voltage * (millis() - last) / 1000; + //} + //_energy[port] += _delta[port]; + } + //last = millis(); + } + + // Current value for slot # index + double value(unsigned char index) { + + if (index < _count) { + _error = SENSOR_ERROR_OK; + unsigned char port = index % _ports; + unsigned char magnitude = index / _ports; + if (magnitude == 0) return _current[port]; + if (magnitude == 1) return _current[port] * _voltage; + //if (magnitude == 2) return _energy[port]; + //if (magnitude == 3) return _delta[port]; + } + + _error = SENSOR_ERROR_OUT_OF_RANGE; + return 0; + + } + + protected: + + unsigned char getChannel(unsigned char port) { + unsigned char count = 0; + unsigned char bit = 1; + for (unsigned char channel=0; channelinitialize(); + _ads->setMode(ADS1115_MODE_CONTINUOUS); + _ads->setRate(ADS1115_RATE_860); + _ads->setGain(ADS1115_PGA_4P096); + #endif + } + + #if EMON_ADSX115_USE_I2CDEVLIB == 0 + + void setChannel(unsigned char channel, bool continuous) { + + // Start with default values + uint16_t config = 0; + config |= ADS1X15_REG_CONFIG_PGA_4_096V; // Set PGA/voltage range + if (continuous) { + config |= ADS1X15_REG_CONFIG_MODE_CONTIN; // Continuous mode (default) + } else { + config |= ADS1X15_REG_CONFIG_MODE_SINGLE; // Single-shot mode + config |= ADS1X15_REG_CONFIG_OS_SINGLE; // Set 'start single-conversion' bit + } + config |= ADS1X15_REG_CONFIG_DR_MASK; // Always at max speed + config |= ADS1X15_REG_CONFIG_CMODE_TRAD; // Traditional comparator (default val) + config |= ADS1X15_REG_CONFIG_CPOL_ACTVLOW; // Alert/Rdy active low (default val) + config |= ADS1X15_REG_CONFIG_CLAT_NONLAT; // Non-latching (default val) + config |= ADS1X15_REG_CONFIG_CQUE_NONE; // Disable the comparator (default val) + config |= ((channel + 4) << 12); // Set single-ended input channel + + // Write config register to the ADC + #if I2C_USE_BRZO + uint8_t buffer[3]; + buffer[0] = ADS1X15_REG_POINTER_CONFIG; + buffer[1] = config >> 8; + buffer[2] = config & 0xFF; + brzo_i2c_start_transaction(_address, I2C_SCL_FREQUENCY); + brzo_i2c_write(buffer, 3, false); + brzo_i2c_end_transaction(); + #else + Wire.beginTransmission(_address); + Wire.write((uint8_t) ADS1X15_REG_POINTER_CONFIG); + Wire.write((uint8_t) (config >> 8)); + Wire.write((uint8_t) (config & 0xFF)); + Wire.endTransmission(); + #endif + + } + + #endif + + double getCurrent(unsigned char channel) { + + #if EMON_ADSX115_USE_I2CDEVLIB + _ads->setMultiplexer(channel + 4); + #else + // Force stop by setting single mode and back to continuous + static unsigned char previous = 9; + if (previous != channel) { + setChannel(previous, false); + delay(50); + previous = channel; + } + setChannel(channel, true); + #endif + + return read(channel, _pivot[channel]); + + } + + unsigned int readADC(unsigned char channel) { + + unsigned int value = 0; + + #if EMON_ADSX115_USE_I2CDEVLIB + value = _ads->getConversion(); + + #elif I2C_USE_BRZO + uint8_t buffer[3]; + buffer[0] = ADS1X15_REG_POINTER_CONVERT; + brzo_i2c_start_transaction(_address, I2C_SCL_FREQUENCY); + brzo_i2c_write(buffer, 1, false); + brzo_i2c_read(buffer, 2, false); + brzo_i2c_end_transaction(); + value |= buffer[0] << 8; + value |= buffer[1]; + + #else + Wire.beginTransmission(_address); + Wire.write(ADS1X15_REG_POINTER_CONVERT); + Wire.endTransmission(); + Wire.requestFrom(_address, (unsigned char) 2); + value |= Wire.read() << 8; + value |= Wire.read(); + #endif + + if (!_is_ads1115) value >>= ADS1015_BIT_SHIFT; + + delayMicroseconds(500); + + return value; + + } + + #if EMON_ADSX115_USE_I2CDEVLIB + ADS1115 * _ads; + #endif + + bool _is_ads1115 = true; + unsigned char _address; + unsigned char _mask; + unsigned char _ports; + double _pivot[ADS1X15_CHANNELS] = {0}; + double _current[ADS1X15_CHANNELS] = {0}; + //unsigned long _energy[ADS1X15_CHANNELS] = {0}; + //unsigned long _delta[ADS1X15_CHANNELS] = {0}; + + +}; From d26f8757632257d8606fa684b89255331e3c61d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xose=20P=C3=A9rez?= Date: Sun, 17 Dec 2017 17:27:49 +0100 Subject: [PATCH 3/9] Remove dependency on I2Cdevlib by default --- code/espurna/config/prototypes.h | 2 +- code/espurna/config/sensors.h | 2 +- code/espurna/sensors/EmonADS1X15Sensor.h | 50 ++++++++++++++---------- 3 files changed, 32 insertions(+), 22 deletions(-) diff --git a/code/espurna/config/prototypes.h b/code/espurna/config/prototypes.h index 2d62b486..4ace7b9c 100644 --- a/code/espurna/config/prototypes.h +++ b/code/espurna/config/prototypes.h @@ -78,7 +78,7 @@ template bool idbSend(const char * topic, unsigned char id, T payloa #if DS18B20_SUPPORT #include #endif -#if EMON_ADS1X15_SUPPORT & EMON_ADSX115_USE_I2CDEVLIB +#if EMON_ADS1X15_SUPPORT & EMON_ADS1X15_USE_I2CDEVLIB #include #endif diff --git a/code/espurna/config/sensors.h b/code/espurna/config/sensors.h index 7a593a84..be574c8b 100644 --- a/code/espurna/config/sensors.h +++ b/code/espurna/config/sensors.h @@ -189,7 +189,7 @@ #define EMON_ADS1X15_SUPPORT 1 // Do not build support by default #endif -#define EMON_ADSX115_USE_I2CDEVLIB 1 // Use I2CDevLib +#define EMON_ADS1X15_USE_I2CDEVLIB 0 // Use I2CDevLib #define EMON_ADS1X15_ADS1115 1 // 0 for ADS10115, 1 for ADS1115 #define EMON_ADS1X15_PORT_MASK 0x08 // A0=1 A1=2 A2=4 A4=8 diff --git a/code/espurna/sensors/EmonADS1X15Sensor.h b/code/espurna/sensors/EmonADS1X15Sensor.h index b5e3309f..e68b9c31 100644 --- a/code/espurna/sensors/EmonADS1X15Sensor.h +++ b/code/espurna/sensors/EmonADS1X15Sensor.h @@ -8,7 +8,7 @@ #include "BaseSensor.h" #include "EmonSensor.h" -#if EMON_ADSX115_USE_I2CDEVLIB +#if EMON_ADS1X15_USE_I2CDEVLIB #include #else #if I2C_USE_BRZO @@ -91,6 +91,7 @@ #define ADS1X15_REG_CONFIG_CQUE_2CONV (0x0001) // Assert ALERT/RDY after two conversions #define ADS1X15_REG_CONFIG_CQUE_4CONV (0x0002) // Assert ALERT/RDY after four conversions #define ADS1X15_REG_CONFIG_CQUE_NONE (0x0003) // Disable the comparator and put ALERT/RDY in high state (default) + #define ADS1X15_CHANNELS 4 #define EMON_ADS1X15_MAGNITUDES_PER_PORT 2 @@ -206,7 +207,7 @@ class EmonADS1X15Sensor : public EmonSensor { //---------------------------------------------------------------------- void init() { - #if EMON_ADSX115_USE_I2CDEVLIB + #if EMON_ADS1X15_USE_I2CDEVLIB _ads = new ADS1115(_address); _ads->initialize(); _ads->setMode(ADS1115_MODE_CONTINUOUS); @@ -215,25 +216,31 @@ class EmonADS1X15Sensor : public EmonSensor { #endif } - #if EMON_ADSX115_USE_I2CDEVLIB == 0 + #if EMON_ADS1X15_USE_I2CDEVLIB == 0 - void setChannel(unsigned char channel, bool continuous) { + void setConfigRegistry(unsigned char channel, bool continuous, bool start) { // Start with default values uint16_t config = 0; - config |= ADS1X15_REG_CONFIG_PGA_4_096V; // Set PGA/voltage range + config |= ADS1X15_REG_CONFIG_PGA_4_096V; // Set PGA/voltage range (0x0200) + config |= ADS1X15_REG_CONFIG_DR_MASK; // Always at max speed (0x00E0) + //config |= ADS1X15_REG_CONFIG_CMODE_TRAD; // Traditional comparator (default val) (0x0000) + //config |= ADS1X15_REG_CONFIG_CPOL_ACTVLOW; // Alert/Rdy active low (default val) (0x0000) + //config |= ADS1X15_REG_CONFIG_CLAT_NONLAT; // Non-latching (default val) (0x0000) + config |= ADS1X15_REG_CONFIG_CQUE_NONE; // Disable the comparator (default val) (0x0003) + if (start) { + config |= ADS1X15_REG_CONFIG_OS_SINGLE; // Start a single-conversion (0x8000) + } if (continuous) { - config |= ADS1X15_REG_CONFIG_MODE_CONTIN; // Continuous mode (default) + //config |= ADS1X15_REG_CONFIG_MODE_CONTIN; // Continuous mode (default) (0x0000) } else { - config |= ADS1X15_REG_CONFIG_MODE_SINGLE; // Single-shot mode - config |= ADS1X15_REG_CONFIG_OS_SINGLE; // Set 'start single-conversion' bit + config |= ADS1X15_REG_CONFIG_MODE_SINGLE; // Single-shot mode (0x0100) } - config |= ADS1X15_REG_CONFIG_DR_MASK; // Always at max speed - config |= ADS1X15_REG_CONFIG_CMODE_TRAD; // Traditional comparator (default val) - config |= ADS1X15_REG_CONFIG_CPOL_ACTVLOW; // Alert/Rdy active low (default val) - config |= ADS1X15_REG_CONFIG_CLAT_NONLAT; // Non-latching (default val) - config |= ADS1X15_REG_CONFIG_CQUE_NONE; // Disable the comparator (default val) - config |= ((channel + 4) << 12); // Set single-ended input channel + config |= ((channel + 4) << 12); // Set single-ended input channel (0x4000 - 0x7000) + + #if EMON_DEBUG + Serial.printf("[EMON] ADS1X115 Config Registry: %04X\n", config); + #endif // Write config register to the ADC #if I2C_USE_BRZO @@ -258,17 +265,20 @@ class EmonADS1X15Sensor : public EmonSensor { double getCurrent(unsigned char channel) { - #if EMON_ADSX115_USE_I2CDEVLIB + #if EMON_ADS1X15_USE_I2CDEVLIB _ads->setMultiplexer(channel + 4); #else // Force stop by setting single mode and back to continuous static unsigned char previous = 9; if (previous != channel) { - setChannel(previous, false); - delay(50); + setConfigRegistry(channel, true, false); + setConfigRegistry(channel, false, false); + setConfigRegistry(channel, false, true); + delay(10); + readADC(channel); previous = channel; } - setChannel(channel, true); + setConfigRegistry(channel, true, true); #endif return read(channel, _pivot[channel]); @@ -279,7 +289,7 @@ class EmonADS1X15Sensor : public EmonSensor { unsigned int value = 0; - #if EMON_ADSX115_USE_I2CDEVLIB + #if EMON_ADS1X15_USE_I2CDEVLIB value = _ads->getConversion(); #elif I2C_USE_BRZO @@ -309,7 +319,7 @@ class EmonADS1X15Sensor : public EmonSensor { } - #if EMON_ADSX115_USE_I2CDEVLIB + #if EMON_ADS1X15_USE_I2CDEVLIB ADS1115 * _ads; #endif From cf27d853cb223d2cdea21cd6711fa4f4e73022e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xose=20P=C3=A9rez?= Date: Sun, 17 Dec 2017 17:37:04 +0100 Subject: [PATCH 4/9] Remove code for I2Cdevlib-ADS1115 --- code/espurna/config/prototypes.h | 3 - code/espurna/config/sensors.h | 4 +- code/espurna/sensors/EmonADS1X15Sensor.h | 140 +++++++++-------------- code/platformio.ini | 1 - 4 files changed, 55 insertions(+), 93 deletions(-) diff --git a/code/espurna/config/prototypes.h b/code/espurna/config/prototypes.h index 4ace7b9c..135814c2 100644 --- a/code/espurna/config/prototypes.h +++ b/code/espurna/config/prototypes.h @@ -78,9 +78,6 @@ template bool idbSend(const char * topic, unsigned char id, T payloa #if DS18B20_SUPPORT #include #endif -#if EMON_ADS1X15_SUPPORT & EMON_ADS1X15_USE_I2CDEVLIB -#include -#endif // ----------------------------------------------------------------------------- // Utils diff --git a/code/espurna/config/sensors.h b/code/espurna/config/sensors.h index be574c8b..2f564410 100644 --- a/code/espurna/config/sensors.h +++ b/code/espurna/config/sensors.h @@ -186,11 +186,9 @@ //-------------------------------------------------------------------------------- #ifndef EMON_ADS1X15_SUPPORT -#define EMON_ADS1X15_SUPPORT 1 // Do not build support by default +#define EMON_ADS1X15_SUPPORT 0 // Do not build support by default #endif -#define EMON_ADS1X15_USE_I2CDEVLIB 0 // Use I2CDevLib - #define EMON_ADS1X15_ADS1115 1 // 0 for ADS10115, 1 for ADS1115 #define EMON_ADS1X15_PORT_MASK 0x08 // A0=1 A1=2 A2=4 A4=8 #define EMON_ADS1X15_I2C_ADDRESS 0x48 // I2C address of the ADS1115 diff --git a/code/espurna/sensors/EmonADS1X15Sensor.h b/code/espurna/sensors/EmonADS1X15Sensor.h index e68b9c31..4c766bad 100644 --- a/code/espurna/sensors/EmonADS1X15Sensor.h +++ b/code/espurna/sensors/EmonADS1X15Sensor.h @@ -8,14 +8,10 @@ #include "BaseSensor.h" #include "EmonSensor.h" -#if EMON_ADS1X15_USE_I2CDEVLIB - #include +#if I2C_USE_BRZO + #include #else - #if I2C_USE_BRZO - #include - #else - #include - #endif + #include #endif #define ADS1015_CONVERSIONDELAY (1) @@ -112,9 +108,6 @@ class EmonADS1X15Sensor : public EmonSensor { } _count = _ports * EMON_ADS1X15_MAGNITUDES_PER_PORT; - // initialize - init(); - // warmup warmup(); @@ -206,80 +199,62 @@ class EmonADS1X15Sensor : public EmonSensor { // I2C //---------------------------------------------------------------------- - void init() { - #if EMON_ADS1X15_USE_I2CDEVLIB - _ads = new ADS1115(_address); - _ads->initialize(); - _ads->setMode(ADS1115_MODE_CONTINUOUS); - _ads->setRate(ADS1115_RATE_860); - _ads->setGain(ADS1115_PGA_4P096); - #endif - } - - #if EMON_ADS1X15_USE_I2CDEVLIB == 0 - - void setConfigRegistry(unsigned char channel, bool continuous, bool start) { + void setConfigRegistry(unsigned char channel, bool continuous, bool start) { + + // Start with default values + uint16_t config = 0; + config |= ADS1X15_REG_CONFIG_PGA_4_096V; // Set PGA/voltage range (0x0200) + config |= ADS1X15_REG_CONFIG_DR_MASK; // Always at max speed (0x00E0) + //config |= ADS1X15_REG_CONFIG_CMODE_TRAD; // Traditional comparator (default val) (0x0000) + //config |= ADS1X15_REG_CONFIG_CPOL_ACTVLOW; // Alert/Rdy active low (default val) (0x0000) + //config |= ADS1X15_REG_CONFIG_CLAT_NONLAT; // Non-latching (default val) (0x0000) + config |= ADS1X15_REG_CONFIG_CQUE_NONE; // Disable the comparator (default val) (0x0003) + if (start) { + config |= ADS1X15_REG_CONFIG_OS_SINGLE; // Start a single-conversion (0x8000) + } + if (continuous) { + //config |= ADS1X15_REG_CONFIG_MODE_CONTIN; // Continuous mode (default) (0x0000) + } else { + config |= ADS1X15_REG_CONFIG_MODE_SINGLE; // Single-shot mode (0x0100) + } + config |= ((channel + 4) << 12); // Set single-ended input channel (0x4000 - 0x7000) - // Start with default values - uint16_t config = 0; - config |= ADS1X15_REG_CONFIG_PGA_4_096V; // Set PGA/voltage range (0x0200) - config |= ADS1X15_REG_CONFIG_DR_MASK; // Always at max speed (0x00E0) - //config |= ADS1X15_REG_CONFIG_CMODE_TRAD; // Traditional comparator (default val) (0x0000) - //config |= ADS1X15_REG_CONFIG_CPOL_ACTVLOW; // Alert/Rdy active low (default val) (0x0000) - //config |= ADS1X15_REG_CONFIG_CLAT_NONLAT; // Non-latching (default val) (0x0000) - config |= ADS1X15_REG_CONFIG_CQUE_NONE; // Disable the comparator (default val) (0x0003) - if (start) { - config |= ADS1X15_REG_CONFIG_OS_SINGLE; // Start a single-conversion (0x8000) - } - if (continuous) { - //config |= ADS1X15_REG_CONFIG_MODE_CONTIN; // Continuous mode (default) (0x0000) - } else { - config |= ADS1X15_REG_CONFIG_MODE_SINGLE; // Single-shot mode (0x0100) - } - config |= ((channel + 4) << 12); // Set single-ended input channel (0x4000 - 0x7000) - - #if EMON_DEBUG - Serial.printf("[EMON] ADS1X115 Config Registry: %04X\n", config); - #endif - - // Write config register to the ADC - #if I2C_USE_BRZO - uint8_t buffer[3]; - buffer[0] = ADS1X15_REG_POINTER_CONFIG; - buffer[1] = config >> 8; - buffer[2] = config & 0xFF; - brzo_i2c_start_transaction(_address, I2C_SCL_FREQUENCY); - brzo_i2c_write(buffer, 3, false); - brzo_i2c_end_transaction(); - #else - Wire.beginTransmission(_address); - Wire.write((uint8_t) ADS1X15_REG_POINTER_CONFIG); - Wire.write((uint8_t) (config >> 8)); - Wire.write((uint8_t) (config & 0xFF)); - Wire.endTransmission(); - #endif + #if EMON_DEBUG + Serial.printf("[EMON] ADS1X115 Config Registry: %04X\n", config); + #endif - } + // Write config register to the ADC + #if I2C_USE_BRZO + uint8_t buffer[3]; + buffer[0] = ADS1X15_REG_POINTER_CONFIG; + buffer[1] = config >> 8; + buffer[2] = config & 0xFF; + brzo_i2c_start_transaction(_address, I2C_SCL_FREQUENCY); + brzo_i2c_write(buffer, 3, false); + brzo_i2c_end_transaction(); + #else + Wire.beginTransmission(_address); + Wire.write((uint8_t) ADS1X15_REG_POINTER_CONFIG); + Wire.write((uint8_t) (config >> 8)); + Wire.write((uint8_t) (config & 0xFF)); + Wire.endTransmission(); + #endif - #endif + } double getCurrent(unsigned char channel) { - #if EMON_ADS1X15_USE_I2CDEVLIB - _ads->setMultiplexer(channel + 4); - #else - // Force stop by setting single mode and back to continuous - static unsigned char previous = 9; - if (previous != channel) { - setConfigRegistry(channel, true, false); - setConfigRegistry(channel, false, false); - setConfigRegistry(channel, false, true); - delay(10); - readADC(channel); - previous = channel; - } - setConfigRegistry(channel, true, true); - #endif + // Force stop by setting single mode and back to continuous + static unsigned char previous = 9; + if (previous != channel) { + setConfigRegistry(channel, true, false); + setConfigRegistry(channel, false, false); + setConfigRegistry(channel, false, true); + delay(10); + readADC(channel); + previous = channel; + } + setConfigRegistry(channel, true, true); return read(channel, _pivot[channel]); @@ -289,10 +264,7 @@ class EmonADS1X15Sensor : public EmonSensor { unsigned int value = 0; - #if EMON_ADS1X15_USE_I2CDEVLIB - value = _ads->getConversion(); - - #elif I2C_USE_BRZO + #if I2C_USE_BRZO uint8_t buffer[3]; buffer[0] = ADS1X15_REG_POINTER_CONVERT; brzo_i2c_start_transaction(_address, I2C_SCL_FREQUENCY); @@ -319,10 +291,6 @@ class EmonADS1X15Sensor : public EmonSensor { } - #if EMON_ADS1X15_USE_I2CDEVLIB - ADS1115 * _ads; - #endif - bool _is_ads1115 = true; unsigned char _address; unsigned char _mask; diff --git a/code/platformio.ini b/code/platformio.ini index 530ff851..0153bb84 100644 --- a/code/platformio.ini +++ b/code/platformio.ini @@ -21,7 +21,6 @@ lib_deps = NtpClientLib OneWire Brzo I2C - I2Cdevlib-ADS1115 EspSoftwareSerial https://bitbucket.org/xoseperez/justwifi.git#1.1.4 https://bitbucket.org/xoseperez/hlw8012.git#1.1.0 From b2e098421427953d8550f94398e05ad36c3aef2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xose=20P=C3=A9rez?= Date: Sun, 17 Dec 2017 18:35:26 +0100 Subject: [PATCH 5/9] Improve memory footprint in filter classes --- code/espurna/filters/BaseFilter.h | 14 ++++++-------- code/espurna/filters/MedianFilter.h | 20 ++++++++++---------- code/espurna/filters/MovingAverageFilter.h | 6 +++--- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/code/espurna/filters/BaseFilter.h b/code/espurna/filters/BaseFilter.h index e86dac37..d11e99d8 100644 --- a/code/espurna/filters/BaseFilter.h +++ b/code/espurna/filters/BaseFilter.h @@ -11,29 +11,27 @@ class BaseFilter { public: BaseFilter() { - _data = new std::vector(); } ~BaseFilter() { - if (_data) delete _data; } virtual void add(double value) { - _data->push_back(value); + _data.push_back(value); } virtual unsigned char count() { - return _data->size(); + return _data.size(); } virtual void reset() { - _data->clear(); + _data.clear(); } virtual double max() { double max = 0; - for (unsigned char i = 1; i < _data->size(); i++) { - if (max < _data->at(i)) max = _data->at(i); + for (unsigned char i = 1; i < _data.size(); i++) { + if (max < _data.at(i)) max = _data.at(i); } return max; } @@ -44,6 +42,6 @@ class BaseFilter { protected: - std::vector *_data; + std::vector _data; }; diff --git a/code/espurna/filters/MedianFilter.h b/code/espurna/filters/MedianFilter.h index 298de511..e85e3793 100644 --- a/code/espurna/filters/MedianFilter.h +++ b/code/espurna/filters/MedianFilter.h @@ -11,8 +11,8 @@ class MedianFilter : public BaseFilter { public: virtual void reset() { - double last = _data->empty() ? 0 : _data->back(); - _data->clear(); + double last = _data.empty() ? 0 : _data.back(); + _data.clear(); add(last); } @@ -20,13 +20,13 @@ class MedianFilter : public BaseFilter { double sum = 0; - if (_data->size() > 2) { + if (_data.size() > 2) { - for (unsigned char i = 1; i <= _data->size() - 2; i++) { + for (unsigned char i = 1; i <= _data.size() - 2; i++) { - double previous = _data->at(i-1); - double current = _data->at(i); - double next = _data->at(i+1); + double previous = _data.at(i-1); + double current = _data.at(i); + double next = _data.at(i+1); if (previous > current) std::swap(previous, current); if (current > next) std::swap(current, next); @@ -36,11 +36,11 @@ class MedianFilter : public BaseFilter { } - sum /= (_data->size() - 2); + sum /= (_data.size() - 2); - } else if (_data->size() > 0) { + } else if (_data.size() > 0) { - sum = _data->front(); + sum = _data.front(); } diff --git a/code/espurna/filters/MovingAverageFilter.h b/code/espurna/filters/MovingAverageFilter.h index a5614164..f6eb40d3 100644 --- a/code/espurna/filters/MovingAverageFilter.h +++ b/code/espurna/filters/MovingAverageFilter.h @@ -14,13 +14,13 @@ class MovingAverageFilter : public BaseFilter { MovingAverageFilter(unsigned char size) { _size = size; for (unsigned char i=0; ipush_back(0); + _data.push_back(0); } } virtual void add(double value) { - _sum = _sum + value - _data->at(_pointer); - _data->at(_pointer) = value; + _sum = _sum + value - _data.at(_pointer); + _data.at(_pointer) = value; _pointer = (_pointer + 1) % _size; } From 1b3927615e9102c079ac876faee0c75a3ebaec0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xose=20P=C3=A9rez?= Date: Sun, 17 Dec 2017 18:35:55 +0100 Subject: [PATCH 6/9] Enable/disable magnitudes for Emon sensors --- code/espurna/config/sensors.h | 3 ++ code/espurna/sensors/EmonADC121Sensor.h | 42 +++++++++++++------- code/espurna/sensors/EmonADS1X15Sensor.h | 50 +++++++++++++++--------- code/espurna/sensors/EmonAnalogSensor.h | 42 +++++++++++++------- code/espurna/sensors/EmonSensor.h | 11 ++++++ 5 files changed, 102 insertions(+), 46 deletions(-) diff --git a/code/espurna/config/sensors.h b/code/espurna/config/sensors.h index 2f564410..88569882 100644 --- a/code/espurna/config/sensors.h +++ b/code/espurna/config/sensors.h @@ -146,6 +146,9 @@ #define EMON_MAX_TIME 250 // Max time in ms to sample #define EMON_FILTER_SPEED 512 // Mobile average filter speed #define EMON_MAINS_VOLTAGE 230 // Mains voltage +#define EMON_REPORT_CURRENT 0 // Calculate current +#define EMON_REPORT_POWER 1 // Calculate power +#define EMON_REPORT_ENERGY 1 // Calculate energy //-------------------------------------------------------------------------------- // Energy Monitor based on interval analog GPIO diff --git a/code/espurna/sensors/EmonADC121Sensor.h b/code/espurna/sensors/EmonADC121Sensor.h index 2a890474..4d6c9b35 100644 --- a/code/espurna/sensors/EmonADC121Sensor.h +++ b/code/espurna/sensors/EmonADC121Sensor.h @@ -32,7 +32,7 @@ class EmonADC121Sensor : public EmonSensor { // Cache _address = address; - _count = 4; + _count = _magnitudes; // Init sensor #if I2C_USE_BRZO @@ -69,10 +69,16 @@ class EmonADC121Sensor : public EmonSensor { // 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_POWER_APPARENT; - if (index == 2) return MAGNITUDE_ENERGY; - if (index == 3) return MAGNITUDE_ENERGY_DELTA; + unsigned char i = 0; + #if EMON_REPORT_CURRENT + if (index == i++) return MAGNITUDE_CURRENT; + #endif + #if EMON_REPORT_POWER + if (index == i++) return MAGNITUDE_POWER_APPARENT; + #endif + #if EMON_REPORT_ENERGY + if (index == i) return MAGNITUDE_ENERGY; + #endif _error = SENSOR_ERROR_OUT_OF_RANGE; return MAGNITUDE_NONE; } @@ -85,19 +91,25 @@ class EmonADC121Sensor : public EmonSensor { // Cache the value static unsigned long last = 0; static double current = 0; - static unsigned long energy_delta = 0; - if ((last == 0) || (millis() - last > 1000)) { current = read(0, _pivot); - energy_delta = current * _voltage * (millis() - last) / 1000; - _energy += energy_delta; + #if EMON_REPORT_ENERGY + _energy += (current * _voltage * (millis() - last) / 1000); + #endif last = millis(); } - if (index == 0) return current; - if (index == 1) return current * _voltage; - if (index == 2) return _energy; - if (index == 3) return energy_delta; + // Report + unsigned char i = 0; + #if EMON_REPORT_CURRENT + if (index == i++) return current; + #endif + #if EMON_REPORT_POWER + if (index == i++) return current * _voltage; + #endif + #if EMON_REPORT_ENERGY + if (index == i) return _energy; + #endif _error = SENSOR_ERROR_OUT_OF_RANGE; return 0; @@ -133,7 +145,9 @@ class EmonADC121Sensor : public EmonSensor { } unsigned char _address; - unsigned long _energy = 0; double _pivot = 0; + #if EMON_REPORT_ENERGY + unsigned long _energy = 0; + #endif }; diff --git a/code/espurna/sensors/EmonADS1X15Sensor.h b/code/espurna/sensors/EmonADS1X15Sensor.h index 4c766bad..76a8ccc8 100644 --- a/code/espurna/sensors/EmonADS1X15Sensor.h +++ b/code/espurna/sensors/EmonADS1X15Sensor.h @@ -89,7 +89,6 @@ #define ADS1X15_REG_CONFIG_CQUE_NONE (0x0003) // Disable the comparator and put ALERT/RDY in high state (default) #define ADS1X15_CHANNELS 4 -#define EMON_ADS1X15_MAGNITUDES_PER_PORT 2 class EmonADS1X15Sensor : public EmonSensor { @@ -106,7 +105,7 @@ class EmonADS1X15Sensor : public EmonSensor { if (mask & 0x01) ++_ports; mask = mask >> 1; } - _count = _ports * EMON_ADS1X15_MAGNITUDES_PER_PORT; + _count = _ports * _magnitudes; // warmup warmup(); @@ -133,39 +132,53 @@ class EmonADS1X15Sensor : public EmonSensor { if (index < _count) { _error = SENSOR_ERROR_OK; unsigned char magnitude = index / _ports; - if (magnitude == 0) return MAGNITUDE_CURRENT; - if (magnitude == 1) return MAGNITUDE_POWER_APPARENT; - //if (magnitude == 2) return MAGNITUDE_ENERGY; - //if (magnitude == 3) return MAGNITUDE_ENERGY_DELTA; + unsigned char i=0; + #if EMON_REPORT_CURRENT + if (magnitude == i++) return MAGNITUDE_CURRENT; + #endif + #if EMON_REPORT_POWER + if (magnitude == i++) return MAGNITUDE_POWER_APPARENT; + #endif + #if EMON_REPORT_ENERGY + if (magnitude == i) return MAGNITUDE_ENERGY; + #endif } _error = SENSOR_ERROR_OUT_OF_RANGE; return MAGNITUDE_NONE; } void pre() { - //static unsigned long last = 0; + static unsigned long last = 0; for (unsigned char port=0; port<_ports; port++) { unsigned char channel = getChannel(port); _current[port] = getCurrent(channel); - //if (last > 0) { - // _delta[port] = _current[port] * _voltage * (millis() - last) / 1000; - //} - //_energy[port] += _delta[port]; + #if EMON_REPORT_ENERGY + _energy[port] += (_current[port] * _voltage * (millis() - last) / 1000); + #endif } - //last = millis(); + last = millis(); } // Current value for slot # index double value(unsigned char index) { if (index < _count) { + _error = SENSOR_ERROR_OK; unsigned char port = index % _ports; unsigned char magnitude = index / _ports; - if (magnitude == 0) return _current[port]; - if (magnitude == 1) return _current[port] * _voltage; - //if (magnitude == 2) return _energy[port]; - //if (magnitude == 3) return _delta[port]; + + unsigned char i=0; + #if EMON_REPORT_CURRENT + if (magnitude == i++) return _current[port]; + #endif + #if EMON_REPORT_POWER + if (magnitude == i++) return _current[port] * _voltage; + #endif + #if EMON_REPORT_ENERGY + if (magnitude == i) return _energy[port]; + #endif + } _error = SENSOR_ERROR_OUT_OF_RANGE; @@ -297,8 +310,9 @@ class EmonADS1X15Sensor : public EmonSensor { unsigned char _ports; double _pivot[ADS1X15_CHANNELS] = {0}; double _current[ADS1X15_CHANNELS] = {0}; - //unsigned long _energy[ADS1X15_CHANNELS] = {0}; - //unsigned long _delta[ADS1X15_CHANNELS] = {0}; + #if EMON_REPORT_ENERGY + unsigned long _energy[ADS1X15_CHANNELS] = {0}; + #endif }; diff --git a/code/espurna/sensors/EmonAnalogSensor.h b/code/espurna/sensors/EmonAnalogSensor.h index 0a7db4de..85e2f66b 100644 --- a/code/espurna/sensors/EmonAnalogSensor.h +++ b/code/espurna/sensors/EmonAnalogSensor.h @@ -16,7 +16,7 @@ class EmonAnalogSensor : public EmonSensor { // Cache _gpio = gpio; - _count = 4; + _count = _magnitudes; // Prepare GPIO pinMode(gpio, INPUT); @@ -41,10 +41,16 @@ class EmonAnalogSensor : public EmonSensor { // 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_POWER_APPARENT; - if (index == 2) return MAGNITUDE_ENERGY; - if (index == 3) return MAGNITUDE_ENERGY_DELTA; + unsigned char i=0; + #if EMON_REPORT_CURRENT + if (index == i++) return MAGNITUDE_CURRENT; + #endif + #if EMON_REPORT_POWER + if (index == i++) return MAGNITUDE_POWER_APPARENT; + #endif + #if EMON_REPORT_ENERGY + if (index == i) return MAGNITUDE_ENERGY; + #endif _error = SENSOR_ERROR_OUT_OF_RANGE; return MAGNITUDE_NONE; } @@ -57,19 +63,25 @@ class EmonAnalogSensor : public EmonSensor { // Cache the value static unsigned long last = 0; static double current = 0; - static unsigned long energy_delta = 0; - if ((last == 0) || (millis() - last > 1000)) { current = read(0, _pivot); - energy_delta = current * _voltage * (millis() - last) / 1000; - _energy += energy_delta; + #if EMON_REPORT_ENERGY + _energy += (current * _voltage * (millis() - last) / 1000); + #endif last = millis(); } - if (index == 0) return current; - if (index == 1) return current * _voltage; - if (index == 2) return _energy; - if (index == 3) return energy_delta; + // Report + unsigned char i=0; + #if EMON_REPORT_CURRENT + if (index == i++) return current; + #endif + #if EMON_REPORT_POWER + if (index == i++) return current * _voltage; + #endif + #if EMON_REPORT_ENERGY + if (index == i) return _energy; + #endif _error = SENSOR_ERROR_OUT_OF_RANGE; return 0; @@ -83,8 +95,10 @@ class EmonAnalogSensor : public EmonSensor { } unsigned char _gpio; - unsigned long _energy = 0; double _pivot = 0; + #if EMON_REPORT_ENERGY + unsigned long _energy = 0; + #endif }; diff --git a/code/espurna/sensors/EmonSensor.h b/code/espurna/sensors/EmonSensor.h index acf8afde..07b5fd48 100644 --- a/code/espurna/sensors/EmonSensor.h +++ b/code/espurna/sensors/EmonSensor.h @@ -19,6 +19,16 @@ class EmonSensor : public BaseSensor { _voltage = voltage; _adc_counts = 1 << bits; + #if EMON_REPORT_CURRENT + ++_magnitudes; + #endif + #if EMON_REPORT_POWER + ++_magnitudes; + #endif + #if EMON_REPORT_ENERGY + ++_magnitudes; + #endif + // Calculate factor _current_factor = ratio * ref / _adc_counts; @@ -110,6 +120,7 @@ class EmonSensor : public BaseSensor { } double _voltage; + unsigned char _magnitudes = 0; unsigned long _adc_counts; unsigned int _multiplier = 1; double _current_factor; From 65831b95e4e85af01eda1b8aff246ff100998342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xose=20P=C3=A9rez?= Date: Sun, 17 Dec 2017 18:39:47 +0100 Subject: [PATCH 7/9] Fix read call in EmonAnalog and EmonADC121 --- code/espurna/config/sensors.h | 2 +- code/espurna/sensors/EmonADC121Sensor.h | 12 ++++++------ code/espurna/sensors/EmonAnalogSensor.h | 12 ++++++------ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/code/espurna/config/sensors.h b/code/espurna/config/sensors.h index 88569882..41bacc96 100644 --- a/code/espurna/config/sensors.h +++ b/code/espurna/config/sensors.h @@ -156,7 +156,7 @@ //-------------------------------------------------------------------------------- #ifndef EMON_ANALOG_SUPPORT -#define EMON_ANALOG_SUPPORT 0 // Do not build support by default +#define EMON_ANALOG_SUPPORT 1 // Do not build support by default #endif #define EMON_ANALOG_CURRENT_RATIO 30 // Current ratio in the clamp (30V/1A) diff --git a/code/espurna/sensors/EmonADC121Sensor.h b/code/espurna/sensors/EmonADC121Sensor.h index 4d6c9b35..ae44d91e 100644 --- a/code/espurna/sensors/EmonADC121Sensor.h +++ b/code/espurna/sensors/EmonADC121Sensor.h @@ -50,7 +50,7 @@ class EmonADC121Sensor : public EmonSensor { #endif // warmup - read(_address); + read(_address, _pivot); } @@ -90,11 +90,10 @@ class EmonADC121Sensor : public EmonSensor { // Cache the value static unsigned long last = 0; - static double current = 0; if ((last == 0) || (millis() - last > 1000)) { - current = read(0, _pivot); + _current = read(0, _pivot); #if EMON_REPORT_ENERGY - _energy += (current * _voltage * (millis() - last) / 1000); + _energy += (_current * _voltage * (millis() - last) / 1000); #endif last = millis(); } @@ -102,10 +101,10 @@ class EmonADC121Sensor : public EmonSensor { // Report unsigned char i = 0; #if EMON_REPORT_CURRENT - if (index == i++) return current; + if (index == i++) return _current; #endif #if EMON_REPORT_POWER - if (index == i++) return current * _voltage; + if (index == i++) return _current * _voltage; #endif #if EMON_REPORT_ENERGY if (index == i) return _energy; @@ -146,6 +145,7 @@ class EmonADC121Sensor : public EmonSensor { unsigned char _address; double _pivot = 0; + double _current = 0; #if EMON_REPORT_ENERGY unsigned long _energy = 0; #endif diff --git a/code/espurna/sensors/EmonAnalogSensor.h b/code/espurna/sensors/EmonAnalogSensor.h index 85e2f66b..8e83dee4 100644 --- a/code/espurna/sensors/EmonAnalogSensor.h +++ b/code/espurna/sensors/EmonAnalogSensor.h @@ -22,7 +22,7 @@ class EmonAnalogSensor : public EmonSensor { pinMode(gpio, INPUT); // warmup - read(_gpio); + read(_gpio, _pivot); } @@ -62,11 +62,10 @@ class EmonAnalogSensor : public EmonSensor { // Cache the value static unsigned long last = 0; - static double current = 0; if ((last == 0) || (millis() - last > 1000)) { - current = read(0, _pivot); + _current = read(0, _pivot); #if EMON_REPORT_ENERGY - _energy += (current * _voltage * (millis() - last) / 1000); + _energy += (_current * _voltage * (millis() - last) / 1000); #endif last = millis(); } @@ -74,10 +73,10 @@ class EmonAnalogSensor : public EmonSensor { // Report unsigned char i=0; #if EMON_REPORT_CURRENT - if (index == i++) return current; + if (index == i++) return _current; #endif #if EMON_REPORT_POWER - if (index == i++) return current * _voltage; + if (index == i++) return _current * _voltage; #endif #if EMON_REPORT_ENERGY if (index == i) return _energy; @@ -96,6 +95,7 @@ class EmonAnalogSensor : public EmonSensor { unsigned char _gpio; double _pivot = 0; + double _current; #if EMON_REPORT_ENERGY unsigned long _energy = 0; #endif From 8d87345d456081f18f0f0d23105c9d334daeb424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xose=20P=C3=A9rez?= Date: Sun, 17 Dec 2017 18:40:44 +0100 Subject: [PATCH 8/9] Make up --- code/espurna/sensors/EmonADS1X15Sensor.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/espurna/sensors/EmonADS1X15Sensor.h b/code/espurna/sensors/EmonADS1X15Sensor.h index 76a8ccc8..65ac4e55 100644 --- a/code/espurna/sensors/EmonADS1X15Sensor.h +++ b/code/espurna/sensors/EmonADS1X15Sensor.h @@ -14,6 +14,8 @@ #include #endif +#define ADS1X15_CHANNELS (4) + #define ADS1015_CONVERSIONDELAY (1) #define ADS1115_CONVERSIONDELAY (8) @@ -88,7 +90,6 @@ #define ADS1X15_REG_CONFIG_CQUE_4CONV (0x0002) // Assert ALERT/RDY after four conversions #define ADS1X15_REG_CONFIG_CQUE_NONE (0x0003) // Disable the comparator and put ALERT/RDY in high state (default) -#define ADS1X15_CHANNELS 4 class EmonADS1X15Sensor : public EmonSensor { From f95e46c4b956f4999540bc4afba5c0454b28a8f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xose=20P=C3=A9rez?= Date: Sun, 17 Dec 2017 21:15:06 +0100 Subject: [PATCH 9/9] Disable EmonAnalog by default --- code/espurna/config/sensors.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/espurna/config/sensors.h b/code/espurna/config/sensors.h index 41bacc96..88569882 100644 --- a/code/espurna/config/sensors.h +++ b/code/espurna/config/sensors.h @@ -156,7 +156,7 @@ //-------------------------------------------------------------------------------- #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 #define EMON_ANALOG_CURRENT_RATIO 30 // Current ratio in the clamp (30V/1A)