SumSqV and countV give the RMS equation somewhere to live in the program. The smaller sketch resets them inside loop, adds one squared centred value at a time and divides by the number collected. Current has its own sum and count. The final file organises the same work differently, with stored arrays and three floating-point totals. I can follow those names to specific operations instead of treating the calculation as one expression that somehow appears at the end.
The route I'm following is: get a reading, interpret its scale, account for the offset, square the changing part, add it to the total, and repeat. After the intended collection, divide by the number of included readings and take the square root. The sensor calibration connects the result to the quantity I want to report. Those steps sound straightforward when I write them in one paragraph. Inside the loop, it becomes easier to forget whether a value is a raw count, an input voltage or a calibrated physical quantity.
I'm using four values to follow the accumulator. In this case, the values entering the RMS part are minus 1, plus 1, minus 1 and plus 1 in arbitrary units. The sum of squares starts at zero. After the first reading it is 1, after the second it is 2, then 3, then 4. Divide by four and I get 1. Its square root is 1. The final answer matches the simple calculation, but now I can see what the loop must have done between the beginning and the answer.
The starting value matters. If the sum begins with an old value left over from an earlier collection, the next average includes more than the readings I think it includes. That doesn't mean this particular program has that mistake; it is a condition I can understand from the algorithm. The same applies to the count. The sum and the divisor have to describe the same collection. If one includes a value the other doesn't, the expression no longer means the average of the squares I intended.
I'm also thinking about the order of the physical conversions. Multiplying a signal by a constant scale has a clear mathematical effect on RMS: the magnitude of the scale multiplies the RMS result. An offset is different. It has to be considered before I decide what signal the squares represent. That’s why I can't treat every constant as the same kind of calibration number. One changes the centre around which the signal varies. Another changes the relationship between a variation and the reported quantity.
The third total in the final file is sum_p, which accumulates voltage-current products rather than squares from a single channel. That distinction matters even when the surrounding loops look similar. One total leads to voltage RMS, another to current RMS and the third to mean active power. The reset defines the start of each collection and the divisor identifies which collection is being averaged. Those are concrete reasons for lines that could otherwise look like ordinary housekeeping.
An example makes the distinction more visible. In this case, the centred signal has an RMS of 0.10 volts and the intended positive scale is 2 units per volt. The scaled RMS is 0.20 units. That simple relationship doesn't mean I can ignore an offset before taking RMS. If the input includes a large middle value, the squares include it too. I need the meaning of each operation, not only an arrangement of operations that produces the answer I expected in one example.
There’s another question that didn't stand out as much in the equation: how large can an intermediate number become? A signed 16-bit raw code can have a magnitude close to 32,768. Squaring a value around that size gives a number around a billion. Adding hundreds of such squares can require much more range than storing one reading. I'm not identifying an overflow in the supplied implementation just by doing this reasoning. I'm noticing why a data type that holds an individual sample may not be enough for an accumulated calculation.
The actual types are visible in these files. The smaller RMS sketch uses double for the squared sums, while the final sketch declares floating-point sums for voltage squares, current squares and products. That gives the range discussion a specific implementation to compare with the paper calculation. I’m not identifying an overflow just because a squared raw count can become large. I’m separating the size of a stored sample from the size and precision required by a total accumulated across many samples.
I also want to distinguish a correct loop from suitable input data. A loop can calculate the RMS of its collected values correctly while the values fail to describe the waveform well. That’s a sampling question. It can also calculate the RMS correctly in raw counts while I apply the wrong conversion afterwards. That’s a scaling question. Splitting those questions doesn't make the whole system trivial, but it stops one successful paper calculation from being mistaken for proof that every reading stage is right.
The small examples are useful because they let me predict the intermediate values. With hundreds of changing readings, I could look at a total without knowing what it ought to be. With four values, I can say what each addition should do. If I need help reading a loop, that is a much better starting point than asking somebody to explain the whole meter. I can point to the operation whose meaning I have lost and compare it with the simple version I understand.
The formula and the loop now tell the same story at different speeds. One shows the complete operation; the other shows what the program keeps while that operation is still happening.