cancel
Showing results for 
Search instead for 
Did you mean: 

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

Lchal.1
Associate II

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

1 ACCEPTED SOLUTION

Accepted Solutions
Javier1
Principal

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)

View solution in original post

4 REPLIES 4
Imen.D
ST Employee

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

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
Lchal.1
Associate II

Thank you

 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

Javier1
Principal

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)