Browse Source

Porting EMON_ADC121 to new sensor module

fastled
Xose Pérez 7 years ago
parent
commit
808528c507
7 changed files with 183 additions and 8 deletions
  1. +1
    -1
      code/espurna/config/general.h
  2. +2
    -2
      code/espurna/config/hardware.h
  3. +24
    -3
      code/espurna/config/sensors.h
  4. +5
    -1
      code/espurna/sensor.ino
  5. +129
    -0
      code/espurna/sensors/EmonADC121Sensor.h
  6. +1
    -1
      code/espurna/sensors/EmonAnalogSensor.h
  7. +21
    -0
      code/espurna/sensors/EmonSensor.h

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

@ -667,7 +667,7 @@ PROGMEM const char* const custom_reset_string[] = {
#define I2C_SUPPORT 1 // I2C enabled (1.98Kb) #define I2C_SUPPORT 1 // I2C enabled (1.98Kb)
#endif #endif
#define I2C_USE_BRZO 0 // Use brzo_i2c library or standard Wire
#define I2C_USE_BRZO 1 // Use brzo_i2c library or standard Wire
#ifndef I2C_SDA_PIN #ifndef I2C_SDA_PIN
#define I2C_SDA_PIN SDA // SDA GPIO (Sonoff => 4) #define I2C_SDA_PIN SDA // SDA GPIO (Sonoff => 4)


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

@ -223,8 +223,8 @@
#define LED1_PIN_INVERSE 1 #define LED1_PIN_INVERSE 1
// Jack is connected to GPIO14 (and with a small hack to GPIO4) // Jack is connected to GPIO14 (and with a small hack to GPIO4)
//#define I2C_SDA_PIN 4
//#define I2C_SCL_PIN 14
#define I2C_SDA_PIN 4
#define I2C_SCL_PIN 14
#elif defined(ITEAD_SONOFF_SV) #elif defined(ITEAD_SONOFF_SV)


+ 24
- 3
code/espurna/config/sensors.h View File

@ -148,12 +148,12 @@
#define EMON_MODE_MSECONDS 2 #define EMON_MODE_MSECONDS 2
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
// Analog Energy Monitor
// Energy Monitor based on interval analog GPIO
// Enable support by passing EMON_ANALOG_SUPPORT=1 build flag // Enable support by passing EMON_ANALOG_SUPPORT=1 build flag
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
#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
#define EMON_ANALOG_MAINS_VOLTAGE 230 // Mains voltage #define EMON_ANALOG_MAINS_VOLTAGE 230 // Mains voltage
@ -167,12 +167,33 @@
#define EMON_ANALOG_WARMUP_VALUE 1000 #define EMON_ANALOG_WARMUP_VALUE 1000
#define EMON_ANALOG_WARMUP_MODE EMON_MODE_MSECONDS #define EMON_ANALOG_WARMUP_MODE EMON_MODE_MSECONDS
#if EMON_ANALOG_SUPPORT #if EMON_ANALOG_SUPPORT
#undef ADC_VCC_ENABLED #undef ADC_VCC_ENABLED
#define ADC_VCC_ENABLED 0 #define ADC_VCC_ENABLED 0
#endif #endif
//--------------------------------------------------------------------------------
// Energy Monitor based on ADC121
// Enable support by passing EMON_ADC121_SUPPORT=1 build flag
//--------------------------------------------------------------------------------
#ifndef EMON_ADC121_SUPPORT
#define EMON_ADC121_SUPPORT 1 // Do not build support by default
#endif
#define EMON_ADC121_I2C_ADDRESS 0x50 // I2C address of the ADC121
#define EMON_ADC121_MAINS_VOLTAGE 230 // Mains voltage
#define EMON_ADC121_CURRENT_RATIO 30 // Current ratio in the clamp (30V/1A)
#define EMON_ADC121_ADC_BITS 12 // ADC depth
#define EMON_ADC121_REFERENCE_VOLTAGE 3.3 // Reference voltage of the ADC
#define EMON_ADC121_READ_VALUE 200
#define EMON_ADC121_READ_MODE EMON_MODE_MSECONDS
#define EMON_ADC121_WARMUP_VALUE 1000
#define EMON_ADC121_WARMUP_MODE EMON_MODE_MSECONDS
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
// Internal power montior // Internal power montior
// Enable support by passing ADC_VCC_ENABLED=1 build flag // Enable support by passing ADC_VCC_ENABLED=1 build flag


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

@ -240,9 +240,13 @@ void sensorInit() {
#if EMON_ANALOG_SUPPORT #if EMON_ANALOG_SUPPORT
#include "sensors/EmonAnalogSensor.h" #include "sensors/EmonAnalogSensor.h"
sensorRegister((BaseSensor *) new EmonAnalogSensor(A0, EMON_ANALOG_MAINS_VOLTAGE, EMON_ANALOG_ADC_BITS, EMON_ANALOG_REFERENCE_VOLTAGE, EMON_ANALOG_CURRENT_RATIO));
sensorRegister(new EmonAnalogSensor(A0, EMON_ANALOG_MAINS_VOLTAGE, EMON_ANALOG_ADC_BITS, EMON_ANALOG_REFERENCE_VOLTAGE, EMON_ANALOG_CURRENT_RATIO));
#endif #endif
#if EMON_ADC121_SUPPORT
#include "sensors/EmonADC121Sensor.h"
sensorRegister(new EmonADC121Sensor(EMON_ADC121_I2C_ADDRESS, EMON_ANALOG_MAINS_VOLTAGE, EMON_ANALOG_ADC_BITS, EMON_ANALOG_REFERENCE_VOLTAGE, EMON_ANALOG_CURRENT_RATIO));
#endif
#if COUNTER_SUPPORT #if COUNTER_SUPPORT
if (_sensor_isr == 0xFF) { if (_sensor_isr == 0xFF) {


+ 129
- 0
code/espurna/sensors/EmonADC121Sensor.h View File

@ -0,0 +1,129 @@
// -----------------------------------------------------------------------------
// Energy monitor sensor
// -----------------------------------------------------------------------------
#pragma once
#include "Arduino.h"
#include "BaseSensor.h"
#include "EmonSensor.h"
#if I2C_USE_BRZO
#include <brzo_i2c.h>
#else
#include <Wire.h>
#endif
// ADC121 Registers
#define ADC121_REG_RESULT 0x00
#define ADC121_REG_ALERT 0x01
#define ADC121_REG_CONFIG 0x02
#define ADC121_REG_LIMITL 0x03
#define ADC121_REG_LIMITH 0x04
#define ADC121_REG_HYST 0x05
#define ADC121_REG_CONVL 0x06
#define ADC121_REG_CONVH 0x07
class EmonADC121Sensor : public EmonSensor {
public:
EmonADC121Sensor(unsigned char address, double voltage, unsigned char bits, double ref, double ratio): EmonSensor(voltage, bits, ref, ratio) {
// Cache
_address = address;
// Init sensor
#if I2C_USE_BRZO
uint8_t buffer[2];
buffer[0] = ADC121_REG_CONFIG;
buffer[1] = 0x00;
brzo_i2c_start_transaction(_address, I2C_SCL_FREQUENCY);
brzo_i2c_write(buffer, 2, false);
brzo_i2c_end_transaction();
#else
Wire.beginTransmission(_address);
Wire.write(ADC121_REG_CONFIG);
Wire.write(0x00);
Wire.endTransmission();
#endif
// warmup
read(EMON_ADC121_WARMUP_VALUE, EMON_ADC121_WARMUP_MODE, _address);
}
// Descriptive name of the sensor
String name() {
char buffer[20];
snprintf(buffer, sizeof(buffer), "EMON @ ADC121 @ I2C (0x%02X)", _address);
return String(buffer);
}
// Descriptive name of the slot # index
String slot(unsigned char index) {
return name();
}
// 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;
_error = SENSOR_ERROR_OUT_OF_RANGE;
return MAGNITUDE_NONE;
}
// Current value for slot # index
double value(unsigned char index) {
_error = SENSOR_ERROR_OK;
// Cache the value
static unsigned long last = 0;
static double current = 0;
if ((last == 0) || (millis() - last > 1000)) {
current = read(EMON_ADC121_READ_VALUE, EMON_ADC121_READ_MODE, _address);
last = millis();
}
if (index == 0) return current;
if (index == 1) return current * _voltage;
_error = SENSOR_ERROR_OUT_OF_RANGE;
return 0;
}
protected:
unsigned int readADC(unsigned char port) {
unsigned int value;
#if I2C_USE_BRZO
uint8_t buffer[2];
buffer[0] = ADC121_REG_RESULT;
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(port);
Wire.write(ADC121_REG_RESULT);
Wire.endTransmission();
Wire.requestFrom(port, (unsigned char) 2);
value = (Wire.read() & 0x0F) << 8;
value = value + Wire.read();
#endif
return value;
}
unsigned char _address;
};

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

@ -28,7 +28,7 @@ class EmonAnalogSensor : public EmonSensor {
// Descriptive name of the sensor // Descriptive name of the sensor
String name() { String name() {
char buffer[20]; char buffer[20];
snprintf(buffer, sizeof(buffer), "ANALOG EMON @ GPIO%d", _gpio);
snprintf(buffer, sizeof(buffer), "EMON @ GPIO%d", _gpio);
return String(buffer); return String(buffer);
} }


+ 21
- 0
code/espurna/sensors/EmonSensor.h View File

@ -7,6 +7,8 @@
#include "Arduino.h" #include "Arduino.h"
#include "BaseSensor.h" #include "BaseSensor.h"
#define EMON_DEBUG 1
class EmonSensor : public BaseSensor { class EmonSensor : public BaseSensor {
public: public:
@ -25,6 +27,14 @@ class EmonSensor : public BaseSensor {
// Calculate multiplier // Calculate multiplier
calculateMultiplier(); calculateMultiplier();
#if EMON_DEBUG
Serial.print("[EMON] Current ratio: "); Serial.println(ratio);
Serial.print("[EMON] Ref. Voltage: "); Serial.println(_voltage);
Serial.print("[EMON] ADC Couns: "); Serial.println(_adc_counts);
Serial.print("[EMON] Current factor: "); Serial.println(_current_factor);
Serial.print("[EMON] Multiplier: "); Serial.println(_multiplier);
#endif
} }
protected: protected:
@ -90,6 +100,17 @@ class EmonSensor : public BaseSensor {
current = (double) (round(current * _multiplier) - 1) / _multiplier; current = (double) (round(current * _multiplier) - 1) / _multiplier;
if (current < 0) current = 0; if (current < 0) current = 0;
#if EMON_DEBUG
Serial.print("[EMON] Total samples: "); Serial.println(samples);
Serial.print("[EMON] Total time (ms): "); Serial.println(millis() - start);
Serial.print("[EMON] Sample frequency (1/s): "); Serial.println(1000 * samples / (millis() - start));
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] RMS value: "); Serial.println(rms);
Serial.print("[EMON] Current: "); Serial.println(current);
#endif
return current; return current;
} }


Loading…
Cancel
Save