cancel
Showing results for 
Search instead for 
Did you mean: 

Unable to understand the value from STPM34

vivek_7
Associate II

I am using this code to read the RMS Voltage and Current. I am also able to get output which I have attached as a .txt file. The expected voltage from the hardware which I am using STPM34 is up to range of 20 V. I am unable to understand where I am going wrong.

#include <HardwareSerial.h> #include <math.h> #include <stdint.h> #include <string.h> #include <Arduino.h> #include "soc/uart_reg.h" const int STPM34_ENABLE_PIN = 4; //Enable pin for STPM3x //UART2 Pins of ESP32 connected to STPM32 const int PIN_16 = 16; //UART Rx pin of STPM3x const int PIN_17 = 17; //UART Tx pin of STPM3x HardwareSerial stpm3xSerial(2); hw_timer_t *timer; const int baud_rate = 9600; uint8_t CRC_u8Checksum = 0; #define BUFFER_SIZE 5 uint16_t STPM3x_RCV[BUFFER_SIZE]; volatile bool timer_call = false; volatile uint8_t u2_chk=0; uint16_t RawRms_volt; uint16_t RawRms_curr; float CalcRMS_volt; float RMS_Volt; float RMS_Curr; float CalcRMS_curr; float active_pwr; float Active_Pwr; float active_nrj; float Active_Nrj; float total_nrj; float Total_Nrj; int32_t energy; int32_t energy_extension; const int TIME_OUT =1000;// 1s timeout int32_t BRR_REG1; int32_t raw_apparent_pwr=0; int64_t calc_apparent_pwr=0; int32_t raw_act_nrj=0; int32_t raw_tot_nrj=0; uint32_t DSP_CR2_LSB; uint32_t DSP_CR2_MSB; uint32_t DSP_CR3_LSB; uint32_t DSP_CR5_LSB; uint32_t DSP_CR5_MSB; uint8_t readAddress; uint8_t writeAddress; uint8_t lsbData; uint8_t msbData; uint8_t endian_data1; uint8_t endian_data2; uint16_t recvd_data; uint32_t stpmData; volatile bool udr = false; volatile int rcvInd = 0; #define RCV_DATA_SIZE 5 uint8_t recvData[RCV_DATA_SIZE]; uint8_t reverse_data1; uint8_t reverse_data2; uint8_t reverse_data3; uint8_t reverse_data4; uint8_t reverse_data5; uint8_t CalcCRC8(uint8_t *pBuf); void Crc8Calc(uint8_t in_Data); uint8_t u8ByteReverse(uint8_t in_byte); bool UartWriteCheck(const uint8_t reg_addr); void snd_cmmnd_stpm3x(uint8_t READ_ADDRESS,uint8_t WRITE_ADDRESS,uint16_t DATA); void rcvData(uint8_t read_addr); void setup() { // put your setup code here, to run once: Serial.begin(115200); Serial.println("Starting ESP32....."); stpm3xSerial.begin(baud_rate,SERIAL_8N1,PIN_16,PIN_17); pinMode(STPM34_ENABLE_PIN,OUTPUT); digitalWrite(STPM34_ENABLE_PIN,HIGH); delay(100); digitalWrite(STPM34_ENABLE_PIN,LOW); Serial.println("STPM3x Enabled"); STPM_UART_init();//Establish STPM3x UART communication stpm3x_init(); stpm3xSerial.setTimeout(1000); } void loop() { // put your main code here, to run repeatedly:") RMS_Volt = readRMSvoltage(); Serial.print("RMS Voltage ="); Serial.print(RMS_Volt); Serial.print("V"); Serial.println(); delay(100); RMS_Curr=readRMScurrent(); Serial.print("RMS Current ="); Serial.print(RMS_Curr); Serial.print("A"); Serial.println(); delay(100); } void STPM_UART_init() { snd_cmmnd_stpm3x(0xFF,0x24,0x4007);//US_REG1 LSB configuration snd_cmmnd_stpm3x(0xFF,0x25,0x000);// US_REG1 MSB configuration Timeout = 1 ms snd_cmmnd_stpm3x(0xFF,0x26,0x0683);// US_REG2 LSB config Buadrate = 9600 bps snd_cmmnd_stpm3x(0xFF,0x27,0x0000);// US_REG2 MSB config Frame delay = 0 snd_cmmnd_stpm3x(0xFF,0x28,0x0066);// US_REG3 snd_cmmnd_stpm3x(0xFF,0x29,0x0000);// US_REG3 } void stpm3x_init() { snd_cmmnd_stpm3x(0xFF,0x00,0x00A0);// DSP_CR1 LSB snd_cmmnd_stpm3x(0xFF,0x01,0x0400); snd_cmmnd_stpm3x(0xFF,0x02,0x00A0); snd_cmmnd_stpm3x(0xFF,0x03,0x2400); snd_cmmnd_stpm3x(0xFF,0x04,0x04E0); snd_cmmnd_stpm3x(0xFF,0x05,0x0020); snd_cmmnd_stpm3x(0xFF,0x06,0x0000); snd_cmmnd_stpm3x(0xFF,0x07,0x0000); snd_cmmnd_stpm3x(0xFF,0x08,0xF800); snd_cmmnd_stpm3x(0xFF,0x09,0x003F); snd_cmmnd_stpm3x(0xFF,0x0A,0xF800); snd_cmmnd_stpm3x(0xFF,0x0B,0x003F); snd_cmmnd_stpm3x(0xFF,0x0C,0xF800); //Calibration register of secondary voltage channel snd_cmmnd_stpm3x(0xFF,0x0D,0x003F); //Swell threshold of secondary voltage channel snd_cmmnd_stpm3x(0xFF,0x0E,0xF800); //Calibration register of secondary current channel snd_cmmnd_stpm3x(0xFF,0x0F,0x003F); //Swell threshold of secondary current channel snd_cmmnd_stpm3x(0xFF,0x10,0x0FFF); //Primary channel RMS upper threshold (for AH) snd_cmmnd_stpm3x(0xFF,0x11,0x0000); snd_cmmnd_stpm3x(0xFF,0x12,0x0FFF); //Primary channel RMS lower threshold (for AH) snd_cmmnd_stpm3x(0xFF,0x13,0x0000); snd_cmmnd_stpm3x(0xFF,0x14,0x0FFF); //Secondary channel RMS upper threshold (for AH snd_cmmnd_stpm3x(0xFF,0x15,0x0000); snd_cmmnd_stpm3x(0xFF,0x16,0x0FFF); //Secondary channel RMS lower threshold (for AH) snd_cmmnd_stpm3x(0xFF,0x17,0x0000); snd_cmmnd_stpm3x(0xFF,0x18,0x0327); //current 1 gain snd_cmmnd_stpm3x(0xFF,0x19,0x0327); snd_cmmnd_stpm3x(0xFF,0x1A,0x0327); //current 2 gain snd_cmmnd_stpm3x(0xFF,0x1B,0x0327); snd_cmmnd_stpm3x(0xFF,0x1C,0x0000); snd_cmmnd_stpm3x(0xFF,0x1D,0x0000); snd_cmmnd_stpm3x(0xFF,0x1E,0x0000); snd_cmmnd_stpm3x(0xFF,0x1F,0x0000); snd_cmmnd_stpm3x(0xFF,0x20,0x777F); snd_cmmnd_stpm3x(0xFF,0x21,0x0204); snd_cmmnd_stpm3x(0xFF,0x22,0x0000); snd_cmmnd_stpm3x(0xFF,0x23,0x0200); } void snd_cmmnd_stpm3x(uint8_t READ_ADDRESS,uint8_t WRITE_ADDRESS,uint16_t DATA) { uint8_t LSB_DATA = 0; uint8_t MSB_DATA = 0; uint8_t CRC_DATA = 0; uint8_t DATA_WITHOUT_CRC[4] = {0,0,0,0}; LSB_DATA = DATA & 0xFF; MSB_DATA = (DATA>>8) & 0xFF; DATA_WITHOUT_CRC[0]=u8ByteReverse(READ_ADDRESS); DATA_WITHOUT_CRC[1]=u8ByteReverse(WRITE_ADDRESS); DATA_WITHOUT_CRC[2]=u8ByteReverse(LSB_DATA); DATA_WITHOUT_CRC[3]=u8ByteReverse(MSB_DATA); // memset(STPM3x_RCV,0,sizeof(STPM3x_RCV));// Clear the uart buffer for stpm3x CRC_DATA = CalcCRC8(DATA_WITHOUT_CRC); CRC_DATA = u8ByteReverse(CRC_DATA); if(UartWriteCheck(DATA_WITHOUT_CRC[0])); delay(1); if(stpm3xSerial.available()) { reverse_data1 = stpm3xSerial.read(); lsbData = u8ByteReverse(reverse_data1); Serial.print("LSB = 0x"); Serial.print(lsbData,HEX);Serial.println(); } if(UartWriteCheck(DATA_WITHOUT_CRC[1])); delay(1); if(stpm3xSerial.available()) { reverse_data2 = stpm3xSerial.read(); endian_data1 = u8ByteReverse(reverse_data2); Serial.print("Byte2 = 0x"); Serial.print(endian_data1,HEX);Serial.println(); } if(UartWriteCheck(DATA_WITHOUT_CRC[2])); delay(1); if(stpm3xSerial.available()) { reverse_data3 = stpm3xSerial.read(); endian_data2 = u8ByteReverse(reverse_data3); Serial.print("Byte3 = 0x"); Serial.print(endian_data2,HEX);Serial.println(); } if(UartWriteCheck(DATA_WITHOUT_CRC[3])); delay(1); if(stpm3xSerial.available()) { reverse_data4 = stpm3xSerial.read(); msbData = u8ByteReverse(reverse_data4); Serial.print("MSB = 0x"); Serial.print(msbData,HEX);Serial.println(); } stpm3xSerial.write(CRC_DATA); } bool UartWriteCheck(const uint8_t reg_addr) { stpm3xSerial.write(reg_addr); uint32_t status_reg = READ_PERI_REG(UART_STATUS_REG(2)); if(status_reg)// & UART_TXFIFO_EMPTY_INT_ENA) { //Serial.println("The data is written STPM34"); return true; } else { Serial.println("The data is not written properly to registers of STPM34"); return false; } } void rcvData(uint8_t read_addr) { //Send data to read from register snd_cmmnd_stpm3x(read_addr,0xFF,0xFFFF); snd_cmmnd_stpm3x(read_addr,0xFF,0xFFFF); } /* uint8_t rcvData(uint8_t read_addr) { uint8_t bytesRead=0; unsigned long start_time = millis(); while(bytesRead<BUFFER_SIZE) { if(stpm3xSerial.available()){ STPM3x_RCV[bytesRead++] = stpm3xSerial.read(); } if(millis() - start_time>100) { Serial.print("Waiting for UART data"); break; } } } */ int32_t nrj_calc(uint32_t raw_nrj) { int64_t calc_nrj = 0; /* manage the 2 U32 to have enougth place to save energy cumulated */ /* Make sure between two reads inside hardware registers if we have to add carry inside ext U32 */ if (((uint32_t)energy>0xA0000000) && ((uint32_t)raw_nrj<0x60000000)) { energy_extension++; } if (((uint32_t)energy<0x60000000) && ((uint32_t)raw_nrj>0xA0000000)) { energy_extension--; } /* save the new result cumulated come from register inside internal structure */ energy = raw_nrj; /* calculate the nrj value and add the 32 bits extension */ calc_nrj = (uint64_t)raw_nrj + ((int64_t)energy_extension<< 32); calc_nrj *= (int64_t)35145; /* multiply by 10 to have in milli- */ calc_nrj *= 10; /* Put the result in 32 bits format */ calc_nrj >>= 32; /* return the nrj value */ return((int32_t)calc_nrj); } /* CRC CALUCULATIOPN */ uint8_t CalcCRC8(uint8_t *pBuf) { void Crc8Calc(uint8_t in_Data); uint8_t i; uint8_t CRC_u8Checksum = 0x00; for (i=0; i<4; i++) { Crc8Calc(pBuf[i]); } return CRC_u8Checksum; } void Crc8Calc(uint8_t in_Data) { uint8_t loc_u8Idx; uint8_t loc_u8Temp=0; for(loc_u8Idx=0;loc_u8Idx<8;loc_u8Idx++) { loc_u8Temp=in_Data^CRC_u8Checksum; CRC_u8Checksum<<=1; if(loc_u8Temp&0x80) { CRC_u8Checksum^=0x7; } in_Data<<=1; } } /* BYTE REVERSE FUNCTION */ uint8_t u8ByteReverse(uint8_t in_byte) { in_byte = ((in_byte >> 1) & 0x55) | ((in_byte << 1) & 0xaa); in_byte = ((in_byte >> 2) & 0x33) | ((in_byte << 2) & 0xcc); in_byte = ((in_byte >> 4) & 0x0F) | ((in_byte << 4) & 0xF0); return in_byte; } float readRMSvoltage() { uint32_t raw_RMS_Voltage = 0; uint64_t calc_RMS_Voltage = 0; uint16_t v1; uint8_t received_data[5] = {0};//array to store received bytes uint8_t revData[5] = {0}; /******** LATCHING ********/ snd_cmmnd_stpm3x(0xFF,0x05,0x0060); /******** Vrms and Irms ********/ rcvData(0x48); raw_RMS_Voltage = (uint32_t)(msbData<<24)|(endian_data2<<16)|(endian_data1<<8)| lsbData; RawRms_volt=raw_RMS_Voltage; Serial.print("Raw RMS Voltage="); Serial.print(RawRms_volt);Serial.println(); raw_RMS_Voltage=(raw_RMS_Voltage&0x7FFF); calc_RMS_Voltage = (uint64_t)raw_RMS_Voltage*116274; calc_RMS_Voltage *= 10; calc_RMS_Voltage >>= 15; CalcRMS_volt=calc_RMS_Voltage/1000; return CalcRMS_volt; } float readRMScurrent() { uint8_t received_data[5] = {0};//array to store receeived bytes uint8_t revData[5] = {0}; uint32_t raw_RMS_Current = 0; uint64_t calc_RMS_Current = 0; /******** LATCHING ********/ snd_cmmnd_stpm3x(0xFF,0x05,0x0060); rcvData(0x48); raw_RMS_Current = (uint32_t)(msbData<<24)|(endian_data2<<16)|(endian_data1<<8)| lsbData; Serial.print("Raw RMS Current="); Serial.print(raw_RMS_Current);Serial.println(); raw_RMS_Current=(raw_RMS_Current>>15); RawRms_curr=raw_RMS_Current; calc_RMS_Current = (uint64_t)raw_RMS_Current*25934; calc_RMS_Current *= 10; calc_RMS_Current >>= 17; CalcRMS_curr=calc_RMS_Current/1000; return CalcRMS_curr; } float readActivePower() { int32_t raw_ACT_power=0; int64_t calc_ACT_power=0; uint8_t received_data[5] = {0};//array to store receeived bytes /******** LATCHING ********/ snd_cmmnd_stpm3x(0xFF,0x05,0x0060); rcvData(0x5C); for(int i=0;i<5;i++) { if(stpm3xSerial.available()) { delay(1); received_data[i] = stpm3xSerial.read(); Serial.print("Received Data Byte:0x"); Serial.print(received_data[i],HEX); Serial.println(); } } for(int i=0;i<5;i++) { raw_ACT_power |= (uint32_t)u8ByteReverse(received_data[i])<<(8*i); } raw_ACT_power=raw_ACT_power&(uint32_t)0x1FFFFFFF; raw_ACT_power <<= 4; // handle sign extension as power is on 28 bits raw_ACT_power >>= 4; calc_ACT_power=((int64_t)raw_ACT_power*30154605); calc_ACT_power *= 10; calc_ACT_power >>= 28; active_pwr=(int32_t)calc_ACT_power/1000;//kW return active_pwr; } float readActiveEnergy() { uint8_t received_data[5] = {0};//array to store receeived bytes /******** LATCHING ********/ snd_cmmnd_stpm3x(0xFF,0x05,0x0060); rcvData(0x54); for(int i=0;i<5;i++) { while(stpm3xSerial.available()) { delay(1); received_data[i] = stpm3xSerial.read(); Serial.print("Received Data Byte:0x"); Serial.print(received_data[i],HEX); Serial.println(); } } for(int i=0;i<5;i++) { raw_act_nrj |= (uint32_t)u8ByteReverse(received_data[i])<<(8*i); } active_nrj=nrj_calc(raw_act_nrj); active_nrj = active_nrj/1000;// dividing by 1000 to get watt hour mWh to Wh return active_nrj; }
View more

 

 

0 REPLIES 0