Skip to main content
Lchal.1
Associate III
February 10, 2021
Solved

How to measure RMS voltage and Current coming from AC supply and calculate

  • February 10, 2021
  • 3 replies
  • 9993 views

Hi, i need to measure rms voltage and current choosing ADC channels in stm32f103.

i selected two channnels in ADC1 to read adc values . By using these channels i need to calculate rms voltage and current . But i am confused how to do it . is it necessary to do calibration also. can anyone help me how to write a code or how to start it please.

Thank you

This topic has been closed for replies.
Best answer by Javier1

True RMS calculation:

1.Detect the 0 crossing (here is where the magic is)

2. offset your adc readings tothat 0

3. calculate the root square of every sample and average the results.

(the more samples you get the more precise your result is)0693W000007EhK5QAK.png 

Cheap-fix RMS calculation:

if your signal is going to have a very stable dc component (same average all the time) you can just make a peak detector and do Vrms=(1/sqrt2)*(Vmax-Vavg)

3 replies

ST Technical Moderator
February 10, 2021

Hello @Lchal.1​ ,

The current can be measured through a resistor: by measuring the voltage across this resistor.

The RMS is an average, so it must average the values taken by the ADC by software.

Perhaps I did not understand your question.

So, I suggest adding more details and clarify your request to increase the chances of getting you an answer.

Imen

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question. Thanks
Lchal.1
Lchal.1Author
Associate III
February 10, 2021

 if(HAL _ADC _Start _DMA(&hadc1, (uint32_t*) adc Buffer, TOTAL_CHANNELS) != HAL_OK)

  return 0;

if(RMS _Sample_ Counter<RMS_TOTAL_SAMPLES) // it is given inside timer interrupt by setting 1kz

{

for(index1=0;index1<2;index1++)

{

temp_ ADC = adc Buffer[index1];

V1[index1] = V1[index1]+((float)temp _ADC*(float)temp _ADC);

V2[index1] = V2[index1]+(float)temp _ADC;

}

RMS _Sample _Counter++;

}

while(1)

{

 Delay_Count++;

 if(Delay_Count>=2500)

 {

  Delay_Count = 0;

  if(RMS_Sample_Counter>=RMS_TOTAL_SAMPLES) // i have set RMS_TOTAL_Samples as 1000

  {

  for(indx=0;indx<2;indx++)

  {

  //RMS_value[indx] = ((sqrtf((V1[indx]/100000.0)-((V2[indx]/100000.0)*(V2[indx]/100000.0))))/15.5);

  RMS_value[indx] = ((sqrtf((V1[indx]/1000.0)-((V2[indx]/1000.0)*(V2[indx]/1000.0))))/caliberate_factor);

  if(RMS_value[indx]>1.5)

  {

  Actual_Amps[indx] = RMS_value[indx];

  }

  else

  {

  Actual_Amps[indx] = 0.0;

  }

 /*

  for(indx=0;indx<3;indx++)

  {

  //Amps_Reading[indx] += 0.1;

  if(Amps_Reading[indx]>30)

  {

  Amps_Reading[indx] = 0;

  }

  Actual_Amps[indx] = Amps_Reading[indx];

  }

 */

  V1[indx] = 0;

  V2[indx] = 0;

  }

  RMS_Sample_Counter = 0;

  }

 }

}

this is the code i have done to calculate rms voltage and current can anyone help me if anything i need to add or is my code correct please

Thank you

Lchal.1
Lchal.1Author
Associate III
February 10, 2021

Thank you

Javier1
Javier1Best answer
Principal
February 10, 2021

True RMS calculation:

1.Detect the 0 crossing (here is where the magic is)

2. offset your adc readings tothat 0

3. calculate the root square of every sample and average the results.

(the more samples you get the more precise your result is)0693W000007EhK5QAK.png 

Cheap-fix RMS calculation:

if your signal is going to have a very stable dc component (same average all the time) you can just make a peak detector and do Vrms=(1/sqrt2)*(Vmax-Vavg)

hit me up in https://www.linkedin.com/in/javiermuñoz/