2024-12-26 08:08 PM
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;
}