/* DESARROLLO DE UN SISTEMA IOT PARA EL MONITOREO Y APOYO EN DIMENSIONAMIENTO DE CONSUMO ENERGETICO PARA LA INDUSTRIA LICORERA DEL CAUCA. Autor: Nelson Eduardo Guevara Muñoz. Corporación Universitaria Autonoma del Cauca. */ #include #include /* STATUS REGISTERS */ #define MeterEn 0x00 // Metering Enable #define ChannelMapI 0x01 // Current Channel Mapping Configuration #define ChannelMapU 0x02 // Voltage Channel Mapping Configuration #define SagPeakDetCfg 0x05 // Sag and Peak Detector Period Configuration #define OVth 0x06 // Over Voltage Threshold #define ZXConfig 0x07 // Zero-Crossing Config #define SagTh 0x08 // Voltage Sag Th #define PhaseLossTh 0x09 // Voltage Phase Losing Th #define INWarnTh 0x0A // Neutral Current (Calculated) Warning Threshold #define OIth 0x0B // Over Current Threshold #define FreqLoTh 0x0C // Low Threshold for Frequency Detection #define FreqHiTh 0x0D // High Threshold for Frequency Detection #define PMPwrCtrl 0x0E // Partial Measurement Mode Power Control #define IRQ0MergeCfg 0x0F // IRQ0 Merge Configuration /* EMM STATUS REGISTERS */ #define SoftReset 0x70 // Software Reset #define EMMState0 0x71 // EMM State 0 #define EMMState1 0x72 // EMM State 1 #define EMMIntState0 0x73 // EMM Interrupt Status 0 #define EMMIntState1 0x74 // EMM Interrupt Status 1 #define EMMIntEn0 0x75 // EMM Interrupt Enable 0 #define EMMIntEn1 0x76 // EMM Interrupt Enable 1 #define LastSPIData 0x78 // Last Read/Write SPI Value #define CRCErrStatus 0x79 // CRC Error Status #define CRCDigest 0x7A // CRC Digest #define CfgRegAccEn 0x7F // Configure Register Access Enable /* LOW POWER MODE REGISTERS - NOT USED */ #define DetectCtrl 0x10 #define DetectTh1 0x11 #define DetectTh2 0x12 #define DetectTh3 0x13 #define PMOffsetA 0x14 #define PMOffsetB 0x15 #define PMOffsetC 0x16 #define PMPGA 0x17 #define PMIrmsA 0x18 #define PMIrmsB 0x19 #define PMIrmsC 0x1A #define PMConfig 0x10B #define PMAvgSamples 0x1C #define PMIrmsLSB 0x1D /* CONFIGURATION REGISTERS */ #define PLconstH 0x31 // High Word of PL_Constant #define PLconstL 0x32 // Low Word of PL_Constant #define MMode0 0x33 // Metering Mode Config #define MMode1 0x34 // PGA Gain Configuration for Current Channels #define PStartTh 0x35 // Startup Power Th (P) #define QStartTh 0x36 // Startup Power Th (Q) #define SStartTh 0x37 // Startup Power Th (S) #define PPhaseTh 0x38 // Startup Power Accum Th (P) #define QPhaseTh 0x39 // Startup Power Accum Th (Q) #define SPhaseTh 0x3A // Startup Power Accum Th (S) /* CALIBRATION REGISTERS */ #define PoffsetA 0x41 // A Line Power Offset (P) #define QoffsetA 0x42 // A Line Power Offset (Q) #define PoffsetB 0x43 // B Line Power Offset (P) #define QoffsetB 0x44 // B Line Power Offset (Q) #define PoffsetC 0x45 // C Line Power Offset (P) #define QoffsetC 0x46 // C Line Power Offset (Q) #define PQGainA 0x47 // A Line Calibration Gain #define PhiA 0x48 // A Line Calibration Angle #define PQGainB 0x49 // B Line Calibration Gain #define PhiB 0x4A // B Line Calibration Angle #define PQGainC 0x4B // C Line Calibration Gain #define PhiC 0x4C // C Line Calibration Angle /* FUNDAMENTAL/HARMONIC ENERGY CALIBRATION REGISTERS */ #define PoffsetAF 0x51 // A Fund Power Offset (P) #define PoffsetBF 0x52 // B Fund Power Offset (P) #define PoffsetCF 0x53 // C Fund Power Offset (P) #define PGainAF 0x54 // A Fund Power Gain (P) #define PGainBF 0x55 // B Fund Power Gain (P) #define PGainCF 0x56 // C Fund Power Gain (P) /* MEASUREMENT CALIBRATION REGISTERS */ #define UgainA 0x61 // A Voltage RMS Gain #define IgainA 0x62 // A Current RMS Gain #define UoffsetA 0x63 // A Voltage Offset #define IoffsetA 0x64 // A Current Offset #define UgainB 0x65 // B Voltage RMS Gain #define IgainB 0x66 // B Current RMS Gain #define UoffsetB 0x67 // B Voltage Offset #define IoffsetB 0x68 // B Current Offset #define UgainC 0x69 // C Voltage RMS Gain #define IgainC 0x6A // C Current RMS Gain #define UoffsetC 0x6B // C Voltage Offset #define IoffsetC 0x6C // C Current Offset #define IoffsetN 0x6E // N Current Offset /* ENERGY REGISTERS */ #define APenergyT 0x80 // Total Forward Active #define APenergyA 0x81 // A Forward Active #define APenergyB 0x82 // B Forward Active #define APenergyC 0x83 // C Forward Active #define ANenergyT 0x84 // Total Reverse Active #define ANenergyA 0x85 // A Reverse Active #define ANenergyB 0x86 // B Reverse Active #define ANenergyC 0x87 // C Reverse Active #define RPenergyT 0x88 // Total Forward Reactive #define RPenergyA 0x89 // A Forward Reactive #define RPenergyB 0x8A // B Forward Reactive #define RPenergyC 0x8B // C Forward Reactive #define RNenergyT 0x8C // Total Reverse Reactive #define RNenergyA 0x8D // A Reverse Reactive #define RNenergyB 0x8E // B Reverse Reactive #define RNenergyC 0x8F // C Reverse Reactive #define SAenergyT 0x90 // Total Apparent Energy #define SenergyA 0x91 // A Apparent Energy #define SenergyB 0x92 // B Apparent Energy #define SenergyC 0x93 // C Apparent Energy /* FUNDAMENTAL / HARMONIC ENERGY REGISTERS */ #define APenergyTF 0xA0 // Total Forward Fund. Energy #define APenergyAF 0xA1 // A Forward Fund. Energy #define APenergyBF 0xA2 // B Forward Fund. Energy #define APenergyCF 0xA3 // C Forward Fund. Energy #define ANenergyTF 0xA4 // Total Reverse Fund Energy #define ANenergyAF 0xA5 // A Reverse Fund. Energy #define ANenergyBF 0xA6 // B Reverse Fund. Energy #define ANenergyCF 0xA7 // C Reverse Fund. Energy #define APenergyTH 0xA8 // Total Forward Harm. Energy #define APenergyAH 0xA9 // A Forward Harm. Energy #define APenergyBH 0xAA // B Forward Harm. Energy #define APenergyCH 0xAB // C Forward Harm. Energy #define ANenergyTH 0xAC // Total Reverse Harm. Energy #define ANenergyAH 0xAD // A Reverse Harm. Energy #define ANenergyBH 0xAE // B Reverse Harm. Energy #define ANenergyCH 0xAF // C Reverse Harm. Energy /* POWER & P.F. REGISTERS */ #define PmeanA 0xB1 // A Mean Power (P) #define PmeanT 0xB0 // Total Mean Power (P) #define PmeanB 0xB2 // B Mean Power (P) #define PmeanC 0xB3 // C Mean Power (P) #define QmeanT 0xB4 // Total Mean Power (Q) #define QmeanA 0xB5 // A Mean Power (Q) #define QmeanB 0xB6 // B Mean Power (Q) #define QmeanC 0xB7 // C Mean Power (Q) #define SmeanT 0xB8 // Total Mean Power (S) #define SmeanA 0xB9 // A Mean Power (S) #define SmeanB 0xBA // B Mean Power (S) #define SmeanC 0xBB // C Mean Power (S) #define PFmeanT 0xBC // Mean Power Factor #define PFmeanA 0xBD // A Power Factor #define PFmeanB 0xBE // B Power Factor #define PFmeanC 0xBF // C Power Factor #define PmeanTLSB 0xC0 // Lower Word (Tot. Act. Power) #define PmeanALSB 0xC1 // Lower Word (A Act. Power) #define PmeanBLSB 0xC2 // Lower Word (B Act. Power) #define PmeanCLSB 0xC3 // Lower Word (C Act. Power) #define QmeanTLSB 0xC4 // Lower Word (Tot. React. Power) #define QmeanALSB 0xC5 // Lower Word (A React. Power) #define QmeanBLSB 0xC6 // Lower Word (B React. Power) #define QmeanCLSB 0xC7 // Lower Word (C React. Power) #define SAmeanTLSB 0xC8 // Lower Word (Tot. App. Power) #define SmeanALSB 0xC9 // Lower Word (A App. Power) #define SmeanBLSB 0xCA // Lower Word (B App. Power) #define SmeanCLSB 0xCB // Lower Word (C App. Power) /* FUND/HARM POWER & V/I RMS REGISTERS */ #define PmeanTF 0xD0 // Total Active Fund. Power #define PmeanAF 0xD1 // A Active Fund. Power #define PmeanBF 0xD2 // B Active Fund. Power #define PmeanCF 0xD3 // C Active Fund. Power #define PmeanTH 0xD4 // Total Active Harm. Power #define PmeanAH 0xD5 // A Active Harm. Power #define PmeanBH 0xD6 // B Active Harm. Power #define PmeanCH 0xD7 // C Active Harm. Power #define UrmsA 0xD9 // A RMS Voltage #define UrmsB 0xDA // B RMS Voltage #define UrmsC 0xDB // C RMS Voltage #define IrmsA 0xDD // A RMS Current #define IrmsB 0xDE // B RMS Current #define IrmsC 0xDF // C RMS Current #define IrmsN 0xD8 // Calculated N RMS Current #define PmeanTFLSB 0xE0 // Lower Word (Tot. Act. Fund. Power) #define PmeanAFLSB 0xE1 // Lower Word (A Act. Fund. Power) #define PmeanBFLSB 0xE2 // Lower Word (B Act. Fund. Power) #define PmeanCFLSB 0xE3 // Lower Word (C Act. Fund. Power) #define PmeanTHLSB 0xE4 // Lower Word (Tot. Act. Harm. Power) #define PmeanAHLSB 0xE5 // Lower Word (A Act. Harm. Power) #define PmeanBHLSB 0xE6 // Lower Word (B Act. Harm. Power) #define PmeanCHLSB 0xE7 // Lower Word (C Act. Harm. Power) ///////////////// 0xE8 // Reserved Register #define UrmsALSB 0xE9 // Lower Word (A RMS Voltage) #define UrmsBLSB 0xEA // Lower Word (B RMS Voltage) #define UrmsCLSB 0xEB // Lower Word (C RMS Voltage) ///////////////// 0xEC // Reserved Register #define IrmsALSB 0xED // Lower Word (A RMS Current) #define IrmsBLSB 0xEE // Lower Word (B RMS Current) #define IrmsCLSB 0xEF // Lower Word (C RMS Current) /* THD, FREQUENCY, ANGLE & TEMPTEMP REGISTERS*/ #define THDNUA 0xF1 // A Voltage THD+N #define THDNUB 0xF2 // B Voltage THD+N #define THDNUC 0xF3 // C Voltage THD+N ///////////////// 0xF4 // Reserved Register #define THDNIA 0xF5 // A Current THD+N #define THDNIB 0xF6 // B Current THD+N #define THDNIC 0xF7 // C Current THD+N #define Freq 0xF8 // Frequency #define PAngleA 0xF9 // A Mean Phase Angle #define PAngleB 0xFA // B Mean Phase Angle #define PAngleC 0xFB // C Mean Phase Angle #define Temp 0xFC // Measured Temperature #define UangleA 0xFD // A Voltage Phase Angle #define UangleB 0xFE // B Voltage Phase Angle #define UangleC 0xFF // C Voltage Phase Angle /* COMMANDS */ #define WRITE 0 // WRITE SPI #define READ 1 // READ SPI #define DEBUG_SERIAL 1 /***** CALIBRATION SETTINGS MMode0 *****/ /* * 0X1087 HEX for 60 Hz (North America) * 0x0087 DEC for 50 hz (rest of the world) default */ /******** MMode1 ******* * 0x00 for 10A (1x) * 0x15 for 100A (2x) * 0x2A for between 100A - 200A (4x) */ /* Initialization Functions */ /*double OffsetCalibrationVI(unsigned short regh_addr, unsigned short regl_addr , unsigned short offset_reg); double GainCalibrationV(unsigned short regh_addr, unsigned short regl_addr, unsigned short gain_reg); double GainCalibrationI(unsigned short regh_addr, unsigned short regl_addr, unsigned short gain_reg); double PowerOffsetCalibration(unsigned short regh_addr, unsigned short regl_addr, unsigned short offset_reg); double PhaseAngle (unsigned short angleRegister); double PowerGain(unsigned short gainRegister); /* Main Electrical Parameters (GET)*/ /*double GetLineVoltageA(); double GetLineVoltageB(); double GetLineVoltageC(); double GetLineCurrentA(); double GetLineCurrentB(); double GetLineCurrentC(); double GetTemperature(); double GetFrequency(); double GetMMode0(); double GetMM0de1();*/ #if defined ESP8266 const int CS_pin = 16; /* D5/14 - CLK D6/12 - MISO D7/13 - MOSI */ #elif defined ESP32 const int CS_pin = 5; /* 18 - CLK 19 - MISO 23 - MOSI */ #elif defined ARDUINO_ESP8266_WEMOS_D1MINI // WeMos mini and D1 R2 const int CS_pin = D8; // WEMOS SS pin #elif defined ARDUINO_ESP8266_ESP12 // Adafruit Huzzah const int CS_pin = 15; // HUZZAH SS pins ( 0 or 15) #elif defined ARDUINO_ARCH_SAMD || defined __AVR_ATmega32U4__ //M0 board || 32u4 SS pin const int CS_pin = 10; #else const int CS_pin = SS; // Use default SS pin for unknown Arduino #endif void setup() { /* Enable SPI */ SPI.begin(); Serial.begin(115200); Serial.println("Connecting to ATM90E32"); #if defined(ENERGIA) SPI.setBitOrder(MSBFIRST); SPI.setDataMode(SPI_MODE0); SPI.setClockDivider(SPI_CLOCK_DIV16); #endif pinMode(CS_pin, OUTPUT); delay(100); digitalWrite(CS_pin,HIGH); delay(2000); Serial.println("MEDIDOR DE ENERGÍA IoT ATM90E32AS"); Serial.println("Puertos SPI conectados"); Serial.println("MOSI: " + String(MOSI)); Serial.println("MISO: " + String(MISO)); Serial.println("SCK: " + String(SCK)); Serial.println("CS: " + String(SS)); Serial.println("--------------------------------------------"); //Initialize registers CommEnergyIC(WRITE, SoftReset, 0x789A); // Perform soft reset CommEnergyIC(WRITE, CfgRegAccEn, 0x55AA); // Enable register config access CommEnergyIC(WRITE, MeterEn, 0x0001); // Enable Metering CommEnergyIC(WRITE, MMode0 , 0x1087); // 60 Hz, muestreo lineas A,B,C, CT o Rogwsky CommEnergyIC(WRITE, MMode1 , 0x0015); // Ganancia de muestreo Serial.println("Calibración Offsset Voltaje"); OffsetCalibrationVI(UrmsA, UrmsALSB, UoffsetA); OffsetCalibrationVI(UrmsB, UrmsBLSB, UoffsetB); OffsetCalibrationVI(UrmsC, UrmsCLSB, UoffsetC); Serial.println("--------------------------------------------"); Serial.println("Calibración Offsset Corriente"); OffsetCalibrationVI(IrmsA, IrmsALSB, IoffsetA); OffsetCalibrationVI(IrmsB, IrmsBLSB, IoffsetB); OffsetCalibrationVI(IrmsC, IrmsCLSB, IoffsetC); Serial.println("--------------------------------------------"); Serial.println("Calibración Ganancia Voltaje"); GainCalibrationV(UrmsA, UrmsALSB, UgainA); GainCalibrationV(UrmsB, UrmsBLSB, UgainB); GainCalibrationV(UrmsC, UrmsCLSB, UgainC); Serial.println("--------------------------------------------"); Serial.println("Calibración Ganancia Corriente"); GainCalibrationI(IrmsA, IrmsALSB, IgainA); GainCalibrationI(IrmsB, IrmsBLSB, IgainB); GainCalibrationI(IrmsC, IrmsCLSB, IgainC); Serial.println("--------------------------------------------"); Serial.println("Calibración Power Offset"); PowerOffsetCalibration(PmeanA, PmeanALSB, PoffsetA); PowerOffsetCalibration(PmeanB, PmeanBLSB, PoffsetB); PowerOffsetCalibration(PmeanC, PmeanCLSB, PoffsetC); PowerOffsetCalibration(QmeanA, QmeanALSB, QoffsetA); PowerOffsetCalibration(QmeanB, QmeanBLSB, QoffsetB); PowerOffsetCalibration(QmeanC, QmeanCLSB, QoffsetC); PowerOffsetCalibration(PmeanAF, PmeanAFLSB, PoffsetAF); PowerOffsetCalibration(PmeanBF, PmeanBFLSB, PoffsetBF); PowerOffsetCalibration(PmeanCF, PmeanCFLSB, PoffsetCF); Serial.println("--------------------------------------------"); Serial.println("Calibración Power Gain y Fase de Angulo"); PowerGain(PQGainA); PowerGain(PQGainB); PowerGain(PQGainC); PhaseAngle(PhiA); PhaseAngle(PhiB); PhaseAngle(PhiC); Serial.println("--------------------------------------------"); CommEnergyIC(WRITE, CfgRegAccEn, 0x0000); // End Config delay(2000); } // VOLTAGE double GetLineVoltageA() { unsigned short voltage = CommEnergyIC(READ, UrmsA, 0xFFFF); return (double)voltage / 100; } double GetLineVoltageB() { unsigned short voltage = CommEnergyIC(READ, UrmsB, 0xFFFF); return (double)voltage / 100; } double GetLineVoltageC() { unsigned short voltage = CommEnergyIC(READ, UrmsC, 0xFFFF); return (double)voltage / 100; } // CURRENT double GetLineCurrentA() { unsigned short current = CommEnergyIC(READ, IrmsA, 0xFFFF); return (double)current / 1000; } double GetLineCurrentB() { unsigned short current = CommEnergyIC(READ, IrmsB, 0xFFFF); return (double)current / 1000; } double GetLineCurrentC() { unsigned short current = CommEnergyIC(READ, IrmsC, 0xFFFF); return (double)current / 1000; } // TEMPERATURE double GetTemperature() { /*CommEnergyIC(WRITE, 0x2FF, 0x55AA); // End Config CommEnergyIC(WRITE, 0x216, 0x5183); // End Config CommEnergyIC(WRITE, 0x219, 0x01C1); // End Config CommEnergyIC(WRITE, 0x2FF, 0x0000); // End Config*/ short int atemp = (short int) CommEnergyIC(READ, 0xFC, 0xFFFF); return (double)atemp; } // FREQUENCY double GetFrequency() { unsigned short freq = CommEnergyIC(READ, Freq, 0xFFFF); return (double)freq / 100; } double GetMMode0() { short int atemp = (short int) CommEnergyIC(READ, MMode0, 0xFFFF); return (double)atemp; } double GetMMode1() { short int atemp = (short int) CommEnergyIC(READ, MMode1, 0xFFFF); return (double)atemp; } //--------------------------- Offset Calibration Voltaje/Current/Power -----------------------------// double OffsetCalibrationVI(unsigned short regh_addr, unsigned short regl_addr , unsigned short offset_reg) { //for getting the lower registers of energy and calculating the offset //this should only be run when all inputs are disconnected uint32_t val, val_h, val_l; uint16_t offset; val_h = CommEnergyIC(READ, regh_addr, 0xFFFF); val_l = CommEnergyIC(READ, regl_addr, 0xFFFF); val = CommEnergyIC(READ, regh_addr, 0xFFFF); val = val_h << 16; //move high register up 16 bits val |= val_l; //concatenate the 2 registers to make 1 32 bit number val = val >> 7; //right shift 7 bits - lowest 7 get ignored val = (~val) + 1; //2s compliment offset = val; //keep lower 16 bits CommEnergyIC(WRITE, offset_reg, (signed short)offset); Serial.println("OffsetCalibrationVI: 0x" + String(offset,HEX)); return uint16_t(offset); } double GainCalibrationV(unsigned short regh_addr, unsigned short regl_addr, unsigned short gain_reg){ uint32_t val, val_h, val_l; uint16_t gain; val_h = CommEnergyIC(READ, regh_addr, 0xFFFF); val_l = CommEnergyIC(READ, regl_addr, 0xFFFF); val_l = val_l >> 8; val = (val_h*0.01)+(val_l*0.01/256); val = (130/val)*32768; gain = val; CommEnergyIC(WRITE, gain_reg, (signed short)gain); Serial.println("GainCalibrationV: 0x" + String(gain,HEX)); return uint16_t(gain); } double GainCalibrationI(unsigned short regh_addr, unsigned short regl_addr, unsigned short gain_reg){ uint32_t val, val_h, val_l; uint16_t gain; val_h = CommEnergyIC(READ, regh_addr, 0xFFFF); val_l = CommEnergyIC(READ, regl_addr, 0xFFFF); val_l = val_l >> 8; val = (val_h*0.001)+(val_l*0.001/256); val = (3.19/val)*32768; gain = val; CommEnergyIC(WRITE, gain_reg, (signed short)gain); Serial.println("GainCalibrationI: 0x" + String(gain,HEX)); return uint16_t(gain); } double PowerOffsetCalibration(unsigned short regh_addr, unsigned short regl_addr, unsigned short offset_reg) { //for getting the lower registers of energy and calculating the offset //should only be run when CT sensors are connected to the meter, //but not connected around wires uint32_t val, val_h, val_l; uint16_t offset; val_h = CommEnergyIC(READ, regh_addr, 0xFFFF); val_l = CommEnergyIC(READ, regl_addr, 0xFFFF); val = CommEnergyIC(READ, regh_addr, 0xFFFF); val = val_h << 16; //move high register up 16 bits val |= val_l; //concatenate the 2 registers to make 1 32 bit number val = (~val) + 1; //2s compliment offset = val; //keep lower 16 bits CommEnergyIC(WRITE, offset_reg, (signed short)offset); Serial.println("PowerOffsetCalibration: 0x" + String(offset,HEX)); return uint16_t(offset); } //−−−−−−−−−−−−−−−−−−−−−−−−−−−Phase Angle Calibration−−−−−−−−−−−−−−−−−−−−−−−−−−−−− void PhaseAngle (unsigned short angleRegister) { float powerCALIB = 0.0037; double PFerror = 0; int phaseAngle = 0; PFerror = 1-(powerCALIB/712); phaseAngle = PFerror*3136.449; //Constante 50Hz = 3763.739 //Constante 60 Hz = 3136.449 CommEnergyIC(WRITE, angleRegister, (signed short)phaseAngle); Serial.println("PhaseAngle: 0x" + String(phaseAngle,HEX)); //return uint16_t(phaseAngle); } //−−−−−−−−−−−−−−−−−−−−−−−−−−−Others Calibrations−−−−−−−−−−−−−−−−−−−−−−−−−−−−− void PowerGain(unsigned short gainRegister) { long PFerror = 0.004; short gain = 0; short error = 0; short POW = pow(2,15); error = -PFerror/(1+PFerror); gain = (error*POW); CommEnergyIC(WRITE, gainRegister, (signed short)gain); Serial.println("Power Gain: 0x" + String(gain,HEX)); //return uint16_t(phaseAngle); } unsigned short CommEnergyIC(unsigned char RW, unsigned short address, unsigned short val) { unsigned char* data = (unsigned char*)&val; unsigned char* adata = (unsigned char*)&address; unsigned short output; unsigned short address1; //SPI interface rate is 200 to 160k bps. It Will need to be slowed down for EnergyIC #if !defined(ENERGIA) && !defined(ESP8266) && !defined(ESP32) && !defined(ARDUINO_ARCH_SAMD) SPISettings settings(200000, MSBFIRST, SPI_MODE0); #endif #if defined(ESP8266) SPISettings settings(200000, MSBFIRST, SPI_MODE2); #endif #if defined(ESP32) SPISettings settings(200000, MSBFIRST, SPI_MODE3); #endif #if defined(ARDUINO_ARCH_SAMD) SPISettings settings(200000, MSBFIRST, SPI_MODE3); #endif // Switch MSB and LSB of value output = (val >> 8) | (val << 8); val = output; // Set R/W flag address |= RW << 15; // Swap byte address address1 = (address >> 8) | (address << 8); address = address1; // Transmit & Receive Data #if !defined(ENERGIA) SPI.beginTransaction(settings); #endif // Chip enable and wait for SPI activation digitalWrite(CS_pin, LOW); delayMicroseconds(10); // Write address byte by byte for (byte i = 0; i < 2; i++) { SPI.transfer (*adata); adata++; } // SPI.transfer16(address); /* Must wait 4 us for data to become valid */ delayMicroseconds(4); // READ Data // Do for each byte in transfer if (RW) { for (byte i = 0; i < 2; i++) { *data = SPI.transfer (0x00); data++; } //val = SPI.transfer16(0x00); } else { for (byte i = 0; i < 2; i++) { SPI.transfer(*data); data++; } // SPI.transfer16(val); } // Chip enable and wait for transaction to end digitalWrite(CS_pin, HIGH); delayMicroseconds(10); #if !defined(ENERGIA) SPI.endTransaction(); #endif output = (val >> 8) | (val << 8); // reverse MSB and LSB return output; // Use with transfer16 // return val; } void loop() { /*Repeatedly fetch some values from the ATM90E32 */ float voltageA,voltageB, voltageC, totalVoltage, currentCT1, currentCT2,currentCT3, totalCurrent, realPower, powerFactor, temp, freq, totalWatts, Mode0, Mode1; temp = GetTemperature(); freq = GetFrequency(); voltageA = GetLineVoltageA(); voltageB = GetLineVoltageB(); voltageC = GetLineVoltageC(); currentCT1 = GetLineCurrentA(); currentCT2 = GetLineCurrentB(); currentCT3 = GetLineCurrentC(); Mode0 = GetMMode0(); Mode1 = GetMMode1(); Serial.println("VALORES ELÉCTRICOS"); Serial.println("Voltaje A: " + String(voltageA) + "V"); Serial.println("Voltaje B: " + String(voltageB) + "V"); Serial.println("Voltaje C: " + String(voltageC) + "V"); Serial.println("CorrienteA: " + String(currentCT1) + "A"); Serial.println("CorrienteB: " + String(currentCT2) + "A"); Serial.println("CorrienteC: " + String(currentCT3) + "A"); Serial.println("Temperatura: " + String(temp) + "Cº"); Serial.println("Frequency: " + String(freq) + "Hz"); Serial.println("MMode0: " + String(Mode0)); Serial.println("MMode1: " + String(Mode1)); Serial.println("\n"); delay(5000); }