cancel
Showing results for 
Search instead for 
Did you mean: 

STPM34 UART communication with ESP32

vivek_7
Visitor

I have developed code in arduino IDE , I am only getting the output receive from UART 04000A075 . I understand that this is the default value in register DSP_CR1. Could someone please tell me what does this mean.
I hereby provide the code for receiving and transmission of signal from STPM34 to ESP32 using UART.

 

 

#include <HardwareSerial.h>
#include <math.h>
#include <stdint.h>
#include <string.h>
#include <Arduino.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 1024
char 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
uint32_t raw_RMS_Voltage  = 0;
uint32_t raw_RMS_Current  = 0;
uint64_t calc_RMS_Voltage = 0;
uint64_t calc_RMS_Current = 0;
int32_t BRR_REG1;
int32_t raw_ACT_power=0;
int64_t calc_ACT_power=0;
int32_t raw_apparent_pwr=0;
int64_t calc_apparent_pwr=0;
int32_t PH1_REG1=0;
int32_t TOT_REG1=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;


void setup() {
  // put your setup code here, to run once:
   Serial.begin(9600);
  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();
  // timer = timerBegin(80);//timer frequency 80 Mhz
  // timerAttachInterrupt(timer,&onTimer);//call function timer handler
  // timerAlarm(timer,50000,true,0);
}

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();
  RMS_Curr=readRMScurrent();
  Serial.print("RMS Current =");
  Serial.print(RMS_Curr);
  Serial.print("A");
  Serial.println();
  Active_Pwr = readActivePower();
  Serial.print("Active Power =");
  Serial.print(Active_Pwr);
  Serial.print("kW");
  Serial.println();
  Active_Nrj = readActiveEnergy();
  Serial.print("Active Energy =");
  Serial.print(Active_Nrj);
  Serial.print("kWh");
  Serial.println();
  delay(100);
  read_stpm3x_init();
  Serial.print("DSP_CR2_LSB=");
  Serial.print(DSP_CR2_LSB,HEX);
  Serial.println();
  Serial.print("DSP_CR2_MSB=");
  Serial.print(DSP_CR2_MSB,HEX);
  Serial.println();
  Serial.print("DSP_CR3_LSB=");
  Serial.print(DSP_CR3_LSB,HEX);
  Serial.println();
  Serial.print("DSP_CR5_LSB=");
  Serial.print(DSP_CR5_LSB,HEX);
  Serial.println();
  Serial.print("DSP_CR5_MSB=");
  Serial.print(DSP_CR5_MSB,HEX);
  Serial.println();
  delay(100);
}

void STPM_UART_init()
{
  snd_cmmnd_stpm3x(0xFF,0x24,0x2007);//US_REG1 LSB configuration
  snd_cmmnd_stpm3x(0xFF,0x25,0x03E8);// 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,0x00);// US_REG2 MSB config Frame delay = 0
  snd_cmmnd_stpm3x(0xFF,0x28,0x00);// US_REG3 
}

void stpm3x_init()
{
  snd_cmmnd_stpm3x(0xFF,0x00,0xA0);// 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,0x0000);
	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 read_stpm3x_init()
{
	rcvData(0x02);
  memcpy(&DSP_CR2_LSB,STPM3x_RCV,4);
	rcvData(0x03);
  memcpy(&DSP_CR2_MSB,STPM3x_RCV,4);
	rcvData(0x04);
  memcpy(&DSP_CR3_LSB,STPM3x_RCV,4);
  rcvData(0x08);
  memcpy(&DSP_CR5_LSB,STPM3x_RCV,4);
  rcvData(0x09);
  memcpy(&DSP_CR5_MSB,STPM3x_RCV,4);
}

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);
				
				CRC_DATA=CalcCRC8(DATA_WITHOUT_CRC);
				CRC_DATA=u8ByteReverse(CRC_DATA);
				memset(STPM3x_RCV,0,sizeof(STPM3x_RCV));// Clear the uart buffer for stpm3x

        //Write to UART
        if(stpm3xSerial.write(READ_ADDRESS)!=1)
        {
          //Handle UART write error
          Serial.println("UART Write error for READ_ADDRESS");
          return;
        }
        if(stpm3xSerial.write(WRITE_ADDRESS)!=1)
        {
          Serial.println("UART Write error for WRITE_ADDRESS");
          return;
        }
        if(stpm3xSerial.write(LSB_DATA)!=1)
        {
          Serial.println("UART Write error for LSB_DATA");
          return;
        }
        if(stpm3xSerial.write(MSB_DATA)!=1)
        {
          Serial.println("UART Write error for MSB_DATA");
          return;
        }
        if(stpm3xSerial.write(CRC_DATA)!=1)
        {
          Serial.println("UART Write error for CRC_DATA");
          return;
        }
}

void rcvData(uint8_t read_addr)
{
  //Send data to read from register
   snd_cmmnd_stpm3x(read_addr,0xFF,0xFFFF);
   //Serial.println(read_addr,HEX);
  while(stpm3xSerial.available())
  {
    char u2_data = stpm3xSerial.read();//Read from UART2
    if(u2_chk<BUFFER_SIZE -1){
    STPM3x_RCV[u2_chk++]=u2_data;
    // Serial.print("Data received by ESP32:");
    // Serial.println(u2_data,HEX);
    }
    else
    {
      Serial.println("Buffer overflow reset");
      u2_chk=0;
    }
    //STPM3x_RCV[u2_chk] = '\0';
    //Serial.print("Data received by ESP32:");
    //Serial.println(STPM3x_RCV);
  }
}

/*
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()
{
     /********		LATCHING		********/
	   snd_cmmnd_stpm3x(0xFF,0x05,0x0060);
  	/********		 Vrms and Irms 		********/
    rcvData(0x48);
    uint32_t raw_RMS_Voltage  = 0;
    uint64_t calc_RMS_Voltage = 0;
    memcpy(&raw_RMS_Voltage,STPM3x_RCV,4);
    RawRms_volt=raw_RMS_Voltage;
    calc_RMS_Voltage = (uint64_t)raw_RMS_Voltage*116274;
    calc_RMS_Voltage *=  10;
		calc_RMS_Voltage >>= 15;
    CalcRMS_volt=calc_RMS_Voltage/1000000;
    return CalcRMS_volt;
}

float readRMScurrent()
{
   /********		LATCHING		********/
	   snd_cmmnd_stpm3x(0xFF,0x05,0x0060);
  rcvData(0x48);
  memcpy(&raw_RMS_Current,STPM3x_RCV,4);	  
  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/1000000;
  return CalcRMS_curr;
}

float readActivePower()
{
     /********		LATCHING		********/
	   snd_cmmnd_stpm3x(0xFF,0x05,0x0060);
    rcvData(0x5C);
		memcpy(&raw_ACT_power,STPM3x_RCV,4);
		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 readApparentRMSpwr()
{
   /********		LATCHING		********/
	   snd_cmmnd_stpm3x(0xFF,0x05,0x0060);
  rcvData(0x62);
  memcpy(&raw_apparent_pwr,STPM3x_RCV,4);
  raw_apparent_pwr=raw_apparent_pwr&(uint32_t)0x1FFFFFFF;
  raw_apparent_pwr<<=4;
  raw_apparent_pwr>>=4;
  calc_apparent_pwr=((int64_t)raw_apparent_pwr*30154605);
}
float readActiveEnergy()
{
     /********		LATCHING		********/
	   snd_cmmnd_stpm3x(0xFF,0x05,0x0060);
    rcvData(0x54);		
		memcpy(&PH1_REG1,STPM3x_RCV,4);
		active_nrj=nrj_calc(PH1_REG1);
		active_nrj = active_nrj/1000;// dividing by 1000 to get watt hour mWh to Wh
    return active_nrj;
}

float readTotalEnergy()
{
     /********		LATCHING		********/
	   snd_cmmnd_stpm3x(0xFF,0x05,0x0060);
    rcvData(0x84);
    memcpy(&TOT_REG1,STPM3x_RCV,4);
    total_nrj=nrj_calc(TOT_REG1);
    total_nrj=total_nrj/1000;//dividing by 1000 to get watt hour mWh to Wh
    return total_nrj;
}

 

 

0 REPLIES 0