Skip to content

Commit

Permalink
Merge pull request #4 from ALLTERCO/shelly
Browse files Browse the repository at this point in the history
Various updates and changes (including one breaking change which LGTM). Thanks for the contribution (and for your excellent products).
  • Loading branch information
pimvanpelt committed Feb 16, 2021
2 parents 207bdb1 + b0fda50 commit b8864e9
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 42 deletions.
17 changes: 12 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,20 @@ enum mgos_app_init_result mgos_app_init(void) {
struct mgos_ade7953 *ade;
// These constants are specific to the specific application circuit.
const struct mgos_ade7953_config ade_cfg = {
const struct mgos_config_ade7953 ade_cfg = {
.voltage_scale = .0000382602,
.voltage_offset = -0.068,
.current_scale = {0.00000949523, 0.00000949523},
.current_offset = {-0.017, -0.017},
.apower_scale = {(1 / 164.0), (1 / 164.0)},
.aenergy_scale = {(1 / 25240.0), (1 / 25240.0)},
.current_scale_0 = 0.00000949523,
.current_scale_1 = 0.00000949523,
.current_offset_0 = -0.017,
.current_offset_1 = -0.017,
.apower_scale_0 = (1 / 164.0),
.apower_scale_1 = (1 / 164.0),
.aenergy_scale_0 = (1 / 25240.0),
.aenergy_scale_1 = (1 / 25240.0),
.voltage_pga_gain = MGOS_ADE7953_PGA_GAIN_1,
.current_pga_gain_0 = MGOS_ADE7953_PGA_GAIN_8,
.current_pga_gain_1 = MGOS_ADE7953_PGA_GAIN_8,
};
if (!(ade = mgos_ade7953_create(mgos_i2c_get_global(), &ade_cfg))) {
return false;
Expand Down
34 changes: 14 additions & 20 deletions include/mgos_ade7953.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,37 +26,26 @@ extern "C" {

struct mgos_ade7953;

struct mgos_ade7953_config {
// Scaling factor to convert voltage channel ADC readings to voltage.
// It depends on the parameters of the voltage divider used on the input.
float voltage_scale;
// Voltage measurement offset, volts.
float voltage_offset;

// Scaling factoris to convert current channel ADC readings to amperes.
// Depends on the shunt parameters.
float current_scale[2];
// Current measurement offsets, in amps.
float current_offset[2];

// Scaling factors to convert active power to watts.
float apower_scale[2];

// Scaling factors to convert active energy to watt-hours.
float aenergy_scale[2];
enum ade7953_pga_gain {
MGOS_ADE7953_PGA_GAIN_1 = 0x00,
MGOS_ADE7953_PGA_GAIN_2 = 0x01,
MGOS_ADE7953_PGA_GAIN_4 = 0x02,
MGOS_ADE7953_PGA_GAIN_8 = 0x03,
MGOS_ADE7953_PGA_GAIN_16 = 0x04,
MGOS_ADE7953_PGA_GAIN_22 = 0x05
};

#if MGOS_ADE7953_ENABLE_I2C
// Create an instance of the driver at the given I2C bus and address.
// Returns a pointer to the object upon success, NULL otherwise.
#include "mgos_i2c.h"
struct mgos_ade7953 *mgos_ade7953_create_i2c(struct mgos_i2c *i2c, const struct mgos_ade7953_config *cfg);
struct mgos_ade7953 *mgos_ade7953_create_i2c(struct mgos_i2c *i2c, const struct mgos_config_ade7953 *cfg);
#define mgos_ade7953_create mgos_ade7953_create_i2c
#endif

#if MGOS_ADE7953_ENABLE_SPI
#include "mgos_spi.h"
struct mgos_ade7953 *mgos_ade7953_create_spi(struct mgos_spi *spi, int cs, const struct mgos_ade7953_config *cfg);
struct mgos_ade7953 *mgos_ade7953_create_spi(struct mgos_spi *spi, int cs, const struct mgos_config_ade7953 *cfg);
#endif

// Write the detected voltage in Volts RMS in the *volts pointer.
Expand All @@ -79,6 +68,11 @@ bool mgos_ade7953_get_apower(struct mgos_ade7953 *dev, int channel, float *watts
// If reset is true, resets the accumulator.
bool mgos_ade7953_get_aenergy(struct mgos_ade7953 *dev, int channel, bool reset, float *wh);

// Write the measured power factor to the *pf pointer.
// Power factor is a dimensionless number in the closed interval of −1 to 1.
// Returns true on success, false otherwise.
bool mgos_ade7953_get_pf(struct mgos_ade7953 *dev, int channel, float *pf);

// Advanced usage: functions to read/write ADE7953 registers.
bool mgos_ade7953_read_reg(struct mgos_ade7953 *dev, uint16_t reg, bool is_signed, int32_t *val);
bool mgos_ade7953_write_reg(struct mgos_ade7953 *dev, uint16_t reg, int32_t val);
Expand Down
19 changes: 19 additions & 0 deletions mos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ conds:
- src/mgos_ade7953_spi.c
libs:
- location: https://github.com/mongoose-os-libs/spi
cdefs:
MGOS_ADE7953_SPI_FREQ: 1000000

- when: cdefs.MGOS_ADE7953_ENABLE_I2C == "1"
apply:
Expand All @@ -24,6 +26,23 @@ conds:
libs:
- location: https://github.com/mongoose-os-libs/i2c

config_schema:
# Abstract data, saved in separate storage
- ["ade7953", "o", {title: "ADE7953 driver configuration", abstract: true}]
- ["ade7953.voltage_scale", "f", {title: "Scaling factor to convert voltage channel ADC readings to voltage"}]
- ["ade7953.voltage_offset", "f", {title: "Voltage measurement offset, volts"}]
- ["ade7953.current_scale_0", "f", {title: "Scaling factor to convert current channel ADC readings to amperes, channel 0"}]
- ["ade7953.current_scale_1", "f", {title: "Scaling factor to convert current channel ADC readings to amperes, channel 1"}]
- ["ade7953.current_offset_0", "f", {title: "Current measurement offsets, in amps, channel 0"}]
- ["ade7953.current_offset_1", "f", {title: "Current measurement offsets, in amps, channel 1"}]
- ["ade7953.apower_scale_0", "f", {title: "Scaling factor to convert active power to watts, channel 0"}]
- ["ade7953.apower_scale_1", "f", {title: "Scaling factor to convert active power to watts, channel 1"}]
- ["ade7953.aenergy_scale_0", "f", {title: "Scaling factor to convert active energy to watt-hours, channel 0"}]
- ["ade7953.aenergy_scale_1", "f", {title: "Scaling factor to convert active energy to watt-hours, channel 1"}]
- ["ade7953.voltage_pga_gain", "i", {title: "Voltage PGA gain, see enum ade7953_pga_gain in mgos_ade7953.h"}]
- ["ade7953.current_pga_gain_0", "i", {title: "Current PGA gain, channel 0, see enum ade7953_pga_gain in mgos_ade7953.h"}]
- ["ade7953.current_pga_gain_1", "i", {title: "Current PGA gain, channel 1, see enum ade7953_pga_gain in mgos_ade7953.h"}]

cdefs:
MGOS_ADE7953_ENABLE_SPI: 0
MGOS_ADE7953_ENABLE_I2C: 1
Expand Down
52 changes: 42 additions & 10 deletions src/mgos_ade7953.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,16 @@ bool mgos_ade7953_read_reg(struct mgos_ade7953 *dev, uint16_t reg, bool is_signe
return true;
}

bool mgos_ade7953_create_common(struct mgos_ade7953 *dev, const struct mgos_ade7953_config *cfg) {
bool mgos_ade7953_create_common(struct mgos_ade7953 *dev, const struct mgos_config_ade7953 *cfg) {
int32_t version;

dev->voltage_scale = cfg->voltage_scale;
for (int i = 0; i < 2; i++) {
dev->current_scale[i] = cfg->current_scale[i];
dev->apower_scale[i] = cfg->apower_scale[i];
dev->aenergy_scale[i] = cfg->aenergy_scale[i];
}
dev->current_scale[0] = cfg->current_scale_0;
dev->apower_scale[0] = cfg->apower_scale_0;
dev->aenergy_scale[0] = cfg->aenergy_scale_0;
dev->current_scale[1] = cfg->current_scale_0;
dev->apower_scale[1] = cfg->apower_scale_0;
dev->aenergy_scale[1] = cfg->aenergy_scale_0;

if (mgos_ade7953_read_reg(dev, MGOS_ADE7953_REG_VERSION, false, &version)) {
LOG(LL_INFO, ("ADE7953 silicon version: 0x%02x (%d)", (int) version, (int) version));
Expand All @@ -113,11 +114,22 @@ bool mgos_ade7953_create_common(struct mgos_ade7953 *dev, const struct mgos_ade7
if (cfg->voltage_offset != 0) {
mgos_ade7953_write_reg(dev, MGOS_ADE7953_REG_VRMSOS, (int32_t)(cfg->voltage_offset / cfg->voltage_scale));
}
if (cfg->current_offset[0] != 0) {
mgos_ade7953_write_reg(dev, MGOS_ADE7953_REG_AIRMSOS, (int32_t)(cfg->current_offset[0] / cfg->current_scale[0]));
if (cfg->current_offset_0 != 0) {
mgos_ade7953_write_reg(dev, MGOS_ADE7953_REG_AIRMSOS, (int32_t)(cfg->current_offset_0 / cfg->current_scale_0));
}
if (cfg->current_offset_1 != 0) {
mgos_ade7953_write_reg(dev, MGOS_ADE7953_REG_BIRMSOS, (int32_t)(cfg->current_offset_1 / cfg->current_scale_1));
}

// Set PGA gains.
if (cfg->voltage_pga_gain != 0) {
mgos_ade7953_write_reg(dev, MGOS_ADE7953_REG_PGA_V, cfg->voltage_pga_gain);
}
if (cfg->current_pga_gain_0 != 0) {
mgos_ade7953_write_reg(dev, MGOS_ADE7953_REG_PGA_IA, cfg->current_pga_gain_0);
}
if (cfg->current_offset[1] != 0) {
mgos_ade7953_write_reg(dev, MGOS_ADE7953_REG_BIRMSOS, (int32_t)(cfg->current_offset[1] / cfg->current_scale[1]));
if (cfg->current_pga_gain_1 != 0) {
mgos_ade7953_write_reg(dev, MGOS_ADE7953_REG_PGA_IB, cfg->current_pga_gain_1);
}

mgos_ade7953_write_reg(dev, MGOS_ADE7953_REG_LCYCMODE, 0x40);
Expand Down Expand Up @@ -215,6 +227,26 @@ bool mgos_ade7953_get_aenergy(struct mgos_ade7953 *dev, int channel, bool reset,
return true;
}

bool mgos_ade7953_get_pf(struct mgos_ade7953 *dev, int channel, float *pf) {
uint16_t reg;
int32_t val;
if (!dev || !pf) return false;
if (channel == 0)
reg = MGOS_ADE7953_REG_PFA;
else if (channel == 1)
reg = MGOS_ADE7953_REG_PFB;
else
return false;
if (!mgos_ade7953_read_reg(dev, reg, true, &val)) {
return false;
}
val &= 0x0000FFFF;
// bit 16 of val determines the sign, bits [0:15] represent the absolute part
// 2^-15 = 0.000030518
*pf = (val & 0x8000) ? /*negative sign*/ -((val & ~0x8000) * 0.000030518) : /*positive sign*/ (val * 0.000030518);
return true;
}

bool mgos_ade7953_destroy(struct mgos_ade7953 **dev) {
if (!*dev) return false;
free(*dev);
Expand Down
2 changes: 1 addition & 1 deletion src/mgos_ade7953_i2c.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "mgos_ade7953_internal.h"
#include "mgos_i2c.h"

struct mgos_ade7953 *mgos_ade7953_create_i2c(struct mgos_i2c *i2c, const struct mgos_ade7953_config *cfg) {
struct mgos_ade7953 *mgos_ade7953_create_i2c(struct mgos_i2c *i2c, const struct mgos_config_ade7953 *cfg) {
struct mgos_ade7953 *dev = NULL;

if (!i2c) return NULL;
Expand Down
4 changes: 3 additions & 1 deletion src/mgos_ade7953_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
#define MGOS_ADE7953_REG_V 0x31C
#define MGOS_ADE7953_REG_ANENERGYA 0x31E
#define MGOS_ADE7953_REG_ANENERGYB 0x31F
#define MGOS_ADE7953_REG_PFA 0x10A
#define MGOS_ADE7953_REG_PFB 0x10B

#define MGOS_ADE7953_REG_IRQSTATA 0x32D
#define MGOS_ADE7953_REG_IRQSTATA_RESET (1 << 20)
Expand All @@ -77,7 +79,7 @@ struct mgos_ade7953 {
float aenergy_scale[2];
};

bool mgos_ade7953_create_common(struct mgos_ade7953 *dev, const struct mgos_ade7953_config *cfg);
bool mgos_ade7953_create_common(struct mgos_ade7953 *dev, const struct mgos_config_ade7953 *cfg);

#if MGOS_ADE7953_ENABLE_I2C
bool mgos_ade7953_write_reg_i2c(struct mgos_ade7953 *dev, uint16_t reg, int size, int32_t val);
Expand Down
10 changes: 5 additions & 5 deletions src/mgos_ade7953_spi.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "mgos_ade7953_internal.h"
#include "mgos_spi.h"

struct mgos_ade7953 *mgos_ade7953_create_spi(struct mgos_spi *spi, int cs, const struct mgos_ade7953_config *cfg) {
struct mgos_ade7953 *mgos_ade7953_create_spi(struct mgos_spi *spi, int cs, const struct mgos_config_ade7953 *cfg) {
struct mgos_ade7953 *dev = NULL;

if (!spi) return NULL;
Expand Down Expand Up @@ -31,8 +31,8 @@ bool mgos_ade7953_write_reg_spi(struct mgos_ade7953 *dev, uint16_t reg, int size

struct mgos_spi_txn txn = {
.cs = dev->spi_cs,
.mode = 3,
.freq = 1e6,
.mode = 0,
.freq = MGOS_ADE7953_SPI_FREQ,
.hd =
{
.tx_data = data_out,
Expand Down Expand Up @@ -60,8 +60,8 @@ bool mgos_ade7953_read_reg_spi(struct mgos_ade7953 *dev, uint16_t reg, int size,

struct mgos_spi_txn txn = {
.cs = dev->spi_cs,
.mode = 3,
.freq = 1e6,
.mode = 0,
.freq = MGOS_ADE7953_SPI_FREQ,
.hd =
{
.tx_data = data_out,
Expand Down

0 comments on commit b8864e9

Please sign in to comment.