cancel
Showing results for 
Search instead for 
Did you mean: 

Sometimes I'm reading strange values for RMS voltage and current on my STPM32, but I do not know why. Is there something very special to concider?

Christian Wächter
Associate III

Hello,

I'm using a STPM32 to measure the ac line voltage and current. It is connected via a galvanic isolator ISO7341CDW to a STM32F072 with SPI. Most of the time, this works just fine. I can read the correct RMS values for I1 and V1 (Register DSP_REG14 at 0x48) as well as the period (Register DSP_REG1 at 0x2E) to convert it to the line frequency. I can change the ac voltage with a adjustable transformer and see the correct values. I'm polling the values every 1 second, but the STPM32 is set to autolatching.

So sometimes something seem to go wrong:

  • Sometimes I get the correct voltage value but a strange value for the current. Starting from a value of ~3000 mA it decreases to zero and then again starts at ~3000 mA etc. When I change the ac input voltage, still the correct voltage value is read by the STPM32, but the current value stays wrong. When the ac voltage is decreased to ~85 VAC, the current decreases to 0 and stays there, even when the ac input voltage is increased again.
  • Sometimes I get the correct current value but a strange value for the voltage. Starting from a value of 400 VAC it decreases to zero and stays there forever, no matter what the input voltage will be changed to after that.
  • Sometimes both the voltage and current values are strange. So both values show the behavior described above.
  • The measurement of the period (register DSP_REG1) works just fine all the time, even when the voltage or current values are strange.

I just read some of the received data from register DSP_REG14 in the Atollic True Studio for debugging purposes. These data frames were received exactly in this order with no other frame in between after flashing and starting the firmware to the STM32F072 in debug mode. The actual ac voltage was ~130 VAC, the actual current was ~240 mA.

1)   rx_data[0]      0x13   (V1 RMS Data [7:0])

   rx_data[1]      0xda   (V1 RMS Data [14:8], C1 RMS Data [15])

   rx_data[2]      0x7f   (C1 RMS Data [23:16])

   rx_data[3]      0x03   (C1 RMS Data [31:24])

   rx_data[4]      0x9d   (CRC)

   VOLTAGE_RMS      461.180 VAC   (calculated)

   CURRENT_RMS      234 mA   (calculated)

2)   rx_data[0]      0xc4   (V1 RMS Data [7:0])

   rx_data[1]      0x18   (V1 RMS Data [14:8], C1 RMS Data [15])

   rx_data[2]      0x82   (C1 RMS Data [23:16])

   rx_data[3]      0x03   (C1 RMS Data [31:24])

   rx_data[4]      0x94   (CRC)

   VOLTAGE_RMS      126.800 VAC   (calculated)

   CURRENT_RMS      234 mA   (calculated)

3)   rx_data[0]      0x12   (V1 RMS Data [7:0])

   rx_data[1]      0x16   (V1 RMS Data [14:8], C1 RMS Data [15])

   rx_data[2]      0x81   (C1 RMS Data [23:16])

   rx_data[3]      0x03   (C1 RMS Data [31:24])

   rx_data[4]      0x3e   (CRC)

   VOLTAGE_RMS      113.000 VAC   (calculated)

   CURRENT_RMS      234 mA   (calculated)

4)   rx_data[0]      0x00   (V1 RMS Data [7:0])

   rx_data[1]      0x00   (V1 RMS Data [14:8], C1 RMS Data [15])

   rx_data[2]      0x80   (C1 RMS Data [23:16])

   rx_data[3]      0x03   (C1 RMS Data [31:24])

   rx_data[4]      0xbf   (CRC)

   VOLTAGE_RMS      0 VAC   (calculated)

   CURRENT_RMS      234 mA   (calculated)

5)   rx_data[0]      0x00   (V1 RMS Data [7:0])

   rx_data[1]      0x80   (V1 RMS Data [14:8], C1 RMS Data [15])

   rx_data[2]      0x82   (C1 RMS Data [23:16])

   rx_data[3]      0x03   (C1 RMS Data [31:24])

   rx_data[4]      0x9e   (CRC)

   VOLTAGE_RMS      0 VAC   (calculated)

   CURRENT_RMS      235 mA   (calculated)

I first thought about corrupted data packages, but it seems like the CRC is right. Also, when the ac input voltage is read wrong, the current value is still perfectly correct. Even Bit 15 of register DSP_REG14 fits to the current value. This Bit represents the LSB of the current value.

I also do not think, that it is a problem due to wrong calculation in the STM32F072 e.g. overflow, as it works most of the time just fine in the full range of ~80 VAC to 270 VAC. Also I'm using uint32_t values there and verified this independently.

In the STM32F072 I'm using this command to receive the data shown above. Is this fine or would be the single command "HAL_SPI_TransmitReceive(&hspi2, tx_data, rx_data, 5, 1000);" be better?

//////// prepare array for reading data
// - first Byte = Address to read = 0x48 = DSP_REG14
// - Byte 2-4 = could be command to write, but will be ignored when set to 0xFF
// - Byte 5 = CRC, calculated by separate function. Set to 0x99 for debugging
uint8_t tx_data[5] = {0x48, 0xFF, 0xFF, 0xFF, 0x99};
  
// reset CS-signal for sending the read request
HAL_GPIO_WritePin(NSS_GPIO_Port, NSS_Pin, GPIO_PIN_RESET);
  
// send and receive request data via SPI
HAL_SPI_Transmit(&hspi2, (uint8_t*) tx_data, 5, 1000) );
  
// set CS-signal
HAL_GPIO_WritePin(NSS_GPIO_Port, NSS_Pin, GPIO_PIN_SET);
 
HAL_Delay(1);
  
// reset CS-signal for receiving requested data
HAL_GPIO_WritePin(NSS_GPIO_Port, NSS_Pin, GPIO_PIN_RESET);
 
// receive data via SPI
HAL_SPI_Receive(&hspi2, (uint8_t *) rx_data, 5, 1000);
  
// set CS-signal
HAL_GPIO_WritePin(NSS_GPIO_Port, NSS_Pin, GPIO_PIN_SET);

Has anyone any idea, what this problem could be about?

1 ACCEPTED SOLUTION

Accepted Solutions
Christian Wächter
Associate III

I found my error in the meantime. I missed the sending of dummy bytes to receive the actual measurement data...

View solution in original post

4 REPLIES 4
Christian Wächter
Associate III

I found my error in the meantime. I missed the sending of dummy bytes to receive the actual measurement data...

Hello. Could you please share what exactly you fixed in your code? I'm having exactly the same problems with stpm32

.STPM: Act e:10065 p:101331 Rea e:127 p:1422 App e:10043 p:101705
18:38:11.690> 
states: dsp_sr1: 00044008 dsp_sr2: 02044008
 rms U:230.57V I:0.43A
....
 
.STPM: Act e:37339 p:7361171 Rea e:17 p:-46066 App e:35105 p:11417695
18:38:25.614> 
states: dsp_sr1: 03144008 dsp_sr2: 03144008
 rms U:226.35V I:50.40A

For a while stpm32 read the correct voltage and current values U: 230.57V I: 0.43A

But after, completely wrong values or 0 values begin to come

with correct values, the value of the registers DSP_SR1 and DSP_SR2

dsp_sr1: 00044008 dsp_sr2: 02044008

with erroneous readings, it starts to come

states: dsp_sr1: 03144008 dsp_sr2: 03144008

The following registers bits are set according to the datasheet description

0x00044008 = "00000000 00000100 01000000 00001000"

0x03144008 = "00000011 00010100 01000000 00001000"

20 - Primary current sigma-delta bitstream stuck

24 - Primary voltage sigma-delta bitstream stuck

25 - Primary voltage period error

What could be causing this?

Christian Wächter
Associate III

As I wrote, I missed to send dummy data to receive the actual data right after it has been requested. In this case, after sending the read request to the STPM32, the SPI clock will be stopped by the SPI master. When the SPI clock is enabled again (e.g. when sending the next read request to the STPM32), the STPM32 still needs to send the data requested previously. These will be send but somehow get corrupted?! The solution is to send enough dummy data with the value 0xFF. This data will be ignored by the STPM32 but keeps the SPI clock turned on, so that the STPM32 data can be received. My routine looks like this:

HAL_StatusTypeDef STPM3x_read_frame(uint8_t * const rx_data, uint8_t read_address, uint8_t CRC_en)
{
  HAL_StatusTypeDef retVal = HAL_OK;
 
  /*******************************************************************************
   * Prepare array for reading data
   * - first Byte = Address to read
   * - Byte 2-4 = could be command to write, but will be ignored when set to 0xFF
   * - Byte 5 = CRC, calculated by STPM3x_send_frame()
   ******************************************************************************/
  uint8_t tx_data[AC_METRO_FRAME_LEN] = {read_address, 0xFF, 0xFF, 0xFF, 0x00};
 
  /*******************************************************************************
   * Set CS and keep it low during the duration of sending and receiving
   ******************************************************************************/
  STPM3x_CS_SET_LOW();
 
  /*******************************************************************************
   * Send the frame with the address to read from to the STPM3x
   ******************************************************************************/
  retVal |= STPM3x_send_frame(tx_data, CRC_en, FALSE);
 
  /*******************************************************************************
   * Change the TX frame to indicate that we want to read now
   ******************************************************************************/
  tx_data[0] = 0xFF;
 
  /*******************************************************************************
   * Calculate CRC
   ******************************************************************************/
  tx_data[AC_METRO_FRAME_LEN-1] = crc8_update( 0x00u, tx_data, AC_METRO_FRAME_LEN-1 );
 
  /*******************************************************************************
   * Receive the requested data frame
   ******************************************************************************/
  retVal |= HAL_SPI_TransmitReceive(&hspi2, (uint8_t*) tx_data, (uint8_t *) rx_data, AC_METRO_FRAME_LEN, 100 );
 
  /*******************************************************************************
   * Set CS high after everything has been transmitted and received
   ******************************************************************************/
  STPM3x_CS_SET_HIGH();
 
  /*******************************************************************************
   * Check if received CRC is correct, but only if CRC was enabled
   ******************************************************************************/
  if ( CRC_en == TRUE )
  {
    if ( rx_data[AC_METRO_FRAME_LEN-1] == crc8_update( 0x00u, rx_data, (AC_METRO_FRAME_LEN-1) ) )
    {
  	  /*******************************************************************************
  	   * CRC correct
  	   ******************************************************************************/
      retVal |= HAL_OK;
    }
    else
    {
	  /*******************************************************************************
	   * CRC wrong, repeat transmission or do something similar
	   ******************************************************************************/
      retVal |= HAL_ERROR;
    }
  }
  return retVal;
}

PPanc.4
Associate

Hello @Christian Wächter​,

Could you please have a look at my question? Did you ever faced similar kind of issue while interfacing stpm32?

https://community.st.com/s/question/0D53W00001exO7uSAE/stpm32-giving-the-value-of-0x00-reg-on-every-request