using System; using Microsoft.SPOT.Hardware; namespace HWModules { public class EnergyMonitorLTC2946 : I2CPortBase { /// /// Input wiring pin for voltage source to measure. /// public enum VoltageSource { Vdd, Adin } private const double minVoltage = 26.5; private readonly byte[] LTC2946_ADIN_MSB_REG = {0x28}; private readonly byte[] LTC2946_CONTROLA_REGISTER = {0x00}; private readonly byte[] LTC2946_DELTA_SENSE_MSB_REG = {0x14}; private readonly byte[] LTC2946_VIN_MSB_REG = {0x1E}; private readonly byte[] registerByte = new byte[1]; private readonly byte[] registerBytes2 = new byte[2]; private EM_VandI emVandI; private I2CDevice.I2CReadTransaction _rt; private I2CDevice.I2CWriteTransaction _wt; private int _xActionReturn; private I2CDevice.I2CTransaction[] _xActions2946 = new I2CDevice.I2CTransaction[2]; public EnergyMonitorLTC2946(I2CDevice.Configuration config, int slotnumber) : base(config, slotnumber) { Source = VoltageSource.Vdd; MilliampsPerCount = 0.5; VoltsPerCount = 0.025; } public EnergyMonitorLTC2946(I2CDevice.Configuration config, VoltageSource source, double voltspercount, double milliampspercount, int slotnumber = 0) : base(config, slotnumber) { Source = source; VoltsPerCount = voltspercount; MilliampsPerCount = milliampspercount; // let's set up the chip so that we are really sampling on adin if (Source == VoltageSource.Adin) SetCtlARegister(RegCTLA.CHCFG_ALTVI, RegCTLA.VOLT_ADIN, RegCTLA.OFFSETCAL_EVERY, RegCTLA.ADINCFG_GND); } //Properties public VoltageSource Source { get; private set; } public double MilliampsPerCount { get; private set; } public double VoltsPerCount { get; private set; } public EM_VandI getVandI() { emVandI.current = double.NaN; emVandI.voltage = double.NaN; // create write buffer to read voltage switch (Source) { case VoltageSource.Vdd: _wt = CreateWriteTransaction(LTC2946_VIN_MSB_REG); break; case VoltageSource.Adin: _wt = CreateWriteTransaction(LTC2946_ADIN_MSB_REG); break; default: return emVandI; } // create read buffer to read the returned data _rt = CreateReadTransaction(registerBytes2); _xActions2946 = new I2CDevice.I2CTransaction[] {_wt, _rt}; _xActionReturn = Execute(_xActions2946, 500); if (_xActionReturn == 0) { //EngrLogger.writeToColumns("Error executing 2946 Transaction = " + xActionReturn.ToString()); } else { emVandI.voltage = VoltsPerCount*((registerBytes2[0] << 4) | (registerBytes2[1] >> 4)); } // create write buffer to read current _xActions2946[0] = CreateWriteTransaction(LTC2946_DELTA_SENSE_MSB_REG); _xActionReturn = Execute(_xActions2946, 500); if (_xActionReturn == 0) { //EngrLogger.writeToColumns("Error executing 2946 Transaction = " + xActionReturn.ToString()); } else { emVandI.current = MilliampsPerCount*((registerBytes2[0] << 4) | (registerBytes2[1] >> 4)); } return emVandI; } public byte ReadCtlARegister() { _wt = CreateWriteTransaction(LTC2946_CONTROLA_REGISTER); _rt = CreateReadTransaction(registerByte); _xActions2946 = new I2CDevice.I2CTransaction[] {_wt, _rt}; _xActionReturn = Execute(_xActions2946, 500); return _xActionReturn == 0 ? byte.MaxValue : registerByte[0]; } private bool SetCtlARegister(RegCTLA chcfgCtla, RegCTLA voltCtla, RegCTLA offsetCtla, RegCTLA adinCtla) { var ctlRegister = (byte) (chcfgCtla | voltCtla | offsetCtla | adinCtla); registerBytes2[0] = LTC2946_CONTROLA_REGISTER[0]; registerBytes2[1] = ctlRegister; _wt = CreateWriteTransaction(registerBytes2); _rt = CreateReadTransaction(registerByte); _xActions2946 = new I2CDevice.I2CTransaction[] {_wt, _rt}; _xActionReturn = Execute(_xActions2946, 500); if (_xActionReturn == 0) { //Debug.Print("Error: Failed to Set CtlA Register"); } else { if (registerByte[0] == ctlRegister) return true; //Debug.Print("GOT Control Register"); } return false; } [Flags] private enum RegCTLA : byte { CHCFG_ALTVI = 0x00, CHCFG_VI16DC = 0x01, CHCFG_VI128DC = 0x02, CHCFG_ADINNODIV = 0x03, CHCFG_ADIN32DC = 0x04, CHCFG_ADIN256DC = 0x05, CHCFG_VONE_IINF = 0x06, CHCFG_SNAPSHOT = 0x07, VOLT_DELTA = 0x00 << 3, VOLT_VDD = 0x01 << 3, VOLT_ADIN = 0x02 << 3, VOLT_SENSEP = 0x03 << 3, OFFSETCAL_EVERY = 0x00 << 5, OFFSETCAL_EVERY16 = 0x01 << 5, OFFSETCAL_EVERY128 = 0x02 << 5, OFFSETCAL_POWERUP = 0x03 << 5, ADINCFG_GND = 0x00 << 7, ADINCFG_INTVCC = 0x01 << 7 } public struct EM_VandI { public double voltage; public double current; } } }