# RMS Voltage Value

it has been a week that I'm struggling with the arduino to measure the RMS Voltage value. By OSC I can see that the RMS voltage value changes around 3V. But I can't see it by serial port. I think my sampling or conversion has problem and I can't find it. I really appreciate it if anyone can take a look at my codes and suggest anything.

``````float readRMS_new(int pin, int vref) {
const unsigned long samplingInterval = 2;  // Interval between RMS calculations in milliseconds
unsigned int readingsSum = 0;   // Sum of squared readings
unsigned int readingsCount = 0; // Number of readings taken
unsigned long lastSamplingTime = 0;  // Time of the last RMS calculation
float rmsVoltage = 0;
float finalVoltage = 0;
float circuitGain = 4.31;  // Gain of the circuit

unsigned long currentTime = millis();  // Current time

// Check if it's time to perform an RMS calculation
if (currentTime - lastSamplingTime >= samplingInterval) {
lastSamplingTime = currentTime;  // Update the last sampling time

// Perform RMS calculation
for (int i = 0; i < 100; i++) {
}

// Calculate RMS voltage
rmsVoltage = rms * 0.0048;
finalVoltage = rmsVoltage * circuitGain;

if (finalVoltage > 0.0f) {
// Print RMS voltage
Serial.print("RMS Voltage: ");
Serial.println(finalVoltage, 3);  // Print with 3 decimal places
}

// Reset variables for the next RMS calculation

return finalVoltage;
}

return 0.0f;  // Return 0 if it's not time to perform an RMS calculation
}
``````

Regards

Farzaneh

• What calls readRMS_new() ? An Interrupt Service Routine or from the loop() ? But, whatever, it is going to be slow with all those maths functions. Commented May 19, 2023 at 13:24
• please describe the signal that is being sampled ... add the description to your question ... do not add a comment Commented May 19, 2023 at 15:26

There are multiple issues with this piece of code:

1. Local variables, i.e. variables defined inside functions or braced blocks, are created each time the execution enters the function or block, and destroyed when it leaves it. Thus, `lastSamplingTime` will always be zero when it is checked. If you want the variable to preserve its value across invocations of the function, you have to either make it global or qualify it as `static`.

2. There is no point in storing the readings in an array, as you never read back any element of the array other than the one you just stored. The array is then eating memory for no good reason.

3. The Arduino will not be able to take more than one reading every 112 µs, or 100 readings in 11.2 ms. There is no point in trying to ensure a 2 ms interval between RMS calculations.

4. There is no point in counting the readings: you know you are taking 100 of them.

5. You should avoid using `pow()` for squaring an integer: this is a floating-point function which is prone to rounding errors.

6. Maybe the most serious issue: on the Mega, an `unsigned int` is 16-bits, and cannot store numbers larger than 65,535. `readingsSum` is very likely going to overflow and give you a meaningless result.

7. Returning zero to mean “no data available” is probably not a very good choice, as zero is also a perfectly valid result. You should consider returning an impossible value, like `-1` (an RMS reading cannot be negative).

Here is how I would write the computation of the RMS value:

``````long readingsSum = 0;
for (int i =0; i < 100; i++) {
}
float rms = sqrt(readingsSum / 100);
``````

Note that `reading` is of type `long` in order to avoid the squaring to overflow.

Thank you all for your time dedication. Finally increasing the sampling and optimize the same codes I could achieve my goals. I will post the functioning code for those who might need it.

``````float readRMS(int pin, int vref) {

int lecturas[200]; // declaring the matrix

float suma = 0; // sum of the squares

float rms = 0;  // squares mean

float volt = 0;  //

float Volt_Final = 0;

for (int cont = 0; cont < 200; cont++) {

delayMicroseconds(200);
}
for (int j = 0; j < 200; j++) {

//Serial.println(lecturas[j]);

suma = suma + pow((lecturas[j] - vref), 2);

//Serial.println(suma);
}
rms = sqrt((suma / 200));

volt = (rms / 1024) * 5;

//Serial.println(volt);

//suma=0;

// Reset variables for the next RMS calculation

rms = 0;

lecturas[200] = 0;

//Volt_Final = (volt * 4.31); //real voltage with circuit gain

return volt;
}
``````
• `lecturas[200] = 0;` is out of bounds. Array indices are 0 to 199
– SBF
Commented May 29, 2023 at 12:16