Rms voltage calculation mikroc code

Status
Not open for further replies.

aswathymohan

Member level 4
Joined
Nov 11, 2012
Messages
68
Helped
5
Reputation
10
Reaction score
5
Trophy points
1,288
Visit site
Activity points
1,727
Hi

I wish to calculate the rms voltage of a sine wave(230V 50hz) and displayed the same on the serial terminal.I am using pic16f877a.I wrote the code,but it is not working properly,can anyone advise me how to solve the issues
1.errors I am getting,not enough ram
2.rms voltage calculation
3.selection of no of samples for accurate measurement

Code:
char uart_rd[50],uart_rd1[50];
float val[100],val1[100],val2[100];
float a,rms;
float sum=0.0;
int i;

void main()
 {
 TRISA=0XFF;

  UART1_Init(9600);               // Initialize UART module at 9600 bps

 while (1) {                     // Endless loop
      for(i=0;i<100;i++)
      {
      val[i]= ADC_Read(1);
      val1[i]=(val[i]*230.0)/1023.0;
      val2[i]=val1[i]*val1[i];
      sum=sum+val2[i];
      }
       a=(float)sum/i;
       rms=sqrt(a);
       FloatToStr(rms,uart_rd);
      strncpy(uart_rd1,uart_rd,5);
       UART1_Write_Text(uart_rd);
       UART1_Write(10);
      UART1_Write(13);
      delay_ms(150);
      }
}
 

1. the PIC has 368 bytes of RAM, you are declaring three float arrays of 4 bytes * 100 entries = 1200 bytes, three single floats = 12 bytes, one int = 2 bytes and 100 chars = 100 bytes. Thats a total of 1,314 bytes, it's no wonder it says you have insufficient RAM.

2. RMS = the square of the mean of the square roots. Simply taking the square root is not the correct calculation. In any case, you need to explain how the AC is fed to the ADC, considering it cannot accept negative voltages.

3. As many as possible but you have to take into account their distribution and position within the cycle. For example, taking 100 samples in the first 2 degrees of the cycle will not give a meaningful voltage, they must be spaced throughout the full 360 degrees.

Brian.
 

thanks for ur rply,

I created a voltage generator circuit using transformer and level shifter circuit to make it into positive voltages (0-5v),
could u pl show me how to solve the memory problem and code for rms voltage calculation

Regards
 

Zip and attach the complete mikroC project files.

Edit:

I haven't done any true rms meters using MCU but see if something like below works.

Is your AC voltage sinusoidal that is does it vary like +240 to -240 or does it vary like +240 (+ve peak Vm), -210 (-ve peak)?

If it varies from +240 to -240 then scale down +240 rms to 3.55V rms, so scaled Vm (peak) will be 5.0V (Vrms = Vm / 0.7071, 5.02 = 3.55 / 0.7071)

Convert this 5.02V to DC using half bridge, So 5.02V AC (Vm) or 3.55V AC rms will be equal to 4.3V DC (0.7V drops across diode)

Use a 22000uF capacitor across ADC pin and gnd. Capacitor charges to 4.7V and this voltage represents scaled AC Vm which is 5.02V or 3.55V rms and also unscaled AC Vm 339.415V or rms 240V.
 
Last edited:

I think the most important quesion is why are you measuring RMS at all. Do you actually need to analyse the waveform or are you simply trying to find the RMS value?

If all you need is the actual RMS voltage and the waveform is, or is close to, a sine wave, use the mathematical relationship between RMS and peak voltages. The peak is easy to find, all you need is a rectifier and storage capacitor. The RMS value is 'Vpeak/sqrt(2)' or if it works out as less code, use 'Vpeak * 0.7071' as sqrt(2) is a constant anyway.

If the waveform is more complex than a sine wave the conversion factor will be different and I would suggest moving the problem into a hardware solution. There are several RMS to DC converters you could use which give the correct RMS value regardless of the waveform shape and they also work over a wide frequency range.

If you really need all those samples there are two options, one is to increase the RAM externally to the 16F877A, the other is to use a PIC with more internal RAM. You could try doing it with a running average routine so you track the average in real time instead of capturing all the samples and processing them afterwards but the math is more complicated that way.


Brian.
 
why i am finding the rms voltage,is to calculate the voltage sag a disturbance occured in the supply using rms voltage method.In this process,the voltage is to be compared with the reference voltage
 

Hi,

how to calculate RMS value:
1) usa a FIX ADC conversion rate(usually controlled by a conter): maybe 32 (integer!) times the lines frequency = at 60 Hz this means 1920 samples per second
2) decide how often you like to output the RMS value: maybe every 6 (integer!) line perid time (at 60Hz this means: 6 / 60 Hz = 0.1 s, = 10 times per second)
3) start the adc conversion
4) loop from 0 to 191 (= 32 x 6 - 1)
5) within this loop:
[If your ADC reading is unipolar then subtract half ADC range (=512) to get -512 .. +511, for transferring unipolar values to bipolar values]
square this value
add it up to the meanSquare value
6) (behind the Loop)
store the meanSquare value into meanSqValue
set meanSquare = 0

7) devide the meanSqValue by 192 (to actually get the MEAN value)
calculate the squareRoot of it
output the squareRoot value
goto 4)
*************

Good programming is: To place the steps 4, 5 and 6 into the AdcConversionFinished interrupt routine, and commit the meanSqValue to the main loop. Commit a flag to indicate a new value to the main loop.

Within the main loop: (steps 6 and 7)
* divide by 192
* calculate the square root
* output the value

*******************

good luck
 
...could u pl show me how to solve the memory problem and code for rms voltage calculation

Once you are dealing with some "signal processing" feature, would be preferable employ a microcontroller with more memory capacity.

Assuming this is not possible, you could perform this square calculation externally by hardware. I´m not sure, but probably even the root square function could be performed the same way.




+++
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…