# How to get RMS voltage and frequency from datapoints read from an ADC?

I have an ADC that samples 4000 times per second or 0.25 ms interval per sample. I would like to extract the RMS and frequency value of the signal being read. How do oscilloscopes and multimeters do this? The target signal is a sinewave.

I have an idea how to calculate frequency but it only works with AC. I count how many number of samples it takes from the first positive reading to change to negative and back to positive again and just multiply that by the interval. I should get the time for 1 cycle, I repeat that for the rest and average them out. Not sure if this is the best method though.

For the voltage, I get the highest and lowest reading of each cycle essentially getting Vpeak-peak. Then just divide that by squareroot of 2 and average it to the rest of the other cycles to get a better reading. Again not sure if this is the best method.

Here is a sample reading (count = 413 at 0.25ms interval). I should get an answer of around 60Hz 0.2 Vac . This is the raw voltage the ADC is reading not yet adjusted for gain.

0.173421356
0.194028019
0.211569668
0.224404791
0.234686593
0.242957526
0.250082904
0.256439526
0.261594088
0.263752444
0.264679559
0.265650304
0.266365989
0.266895564
0.267103704
0.266593726
0.261928256
0.248517781
0.228441123
0.208131004
0.186009858
0.161443396
0.13789932
0.116488709
0.095282375
0.071309289
0.044879871
0.018148901
-0.007538367
-0.031667236
-0.054018122
-0.075290975
-0.096386444
-0.117877307
-0.217307021
-0.228869418
-0.23827403
-0.245405703
-0.251243192
-0.257045347
-0.261500676
-0.263937552
-0.265401824
-0.266356262
-0.26698211
-0.267347463
-0.267451604
-0.266062148
-0.257521851
-0.240745239
-0.220487907
-0.200148034
-0.176438591
-0.151111812
-0.128481833
-0.107821382
-0.085257636
-0.059480245
-0.032984451
-0.007251693
0.017276575
0.04012342
0.061572368
0.08264309
0.104297317
0.126226059
0.147842091
0.168563338
0.189433645
0.207972933
0.221857193
0.232293061
0.240768128
0.247950727
0.254429657
0.260187752
0.263255055
0.264360126
0.265281947
0.266137393
0.266711601
0.266975816
0.266675266
0.263043912
0.251704246
0.233763913
0.213855769
0.19117844
0.166552468
0.143202656
0.121908059
0.100506032
0.076729068
0.051069981
0.024681905
-0.001622057
-0.02649937
-0.048928362
-0.069845875
-0.09085909
-0.112659372
-0.134425465
-0.155744094
-0.17640712
-0.196649289
-0.213999821
-0.226405505
-0.236240558
-0.243890076
-0.25005129
-0.255989916
-0.260918172
-0.263632281
-0.265196403
-0.266208204
-0.266830905
-0.267221721
-0.267460044
-0.26693476
-0.261019595
-0.245307427
-0.224498776
-0.205086017
-0.182742713
-0.157132263
-0.133087079
-0.112573256
-0.091028749
-0.065625294
-0.03884583
-0.013123943
0.011675407
0.03505011
0.056656701
0.077473793
0.099179089
0.121485486
0.143106096
0.163808175
0.184864734
0.20400126
0.218984582
0.23010023
0.239431028
0.246908885
0.25354746
0.259686644
0.263131888
0.264209493
0.265181096
0.266150697
0.266768821
0.267111715
0.26703461
0.264799722
0.255499107
0.237822132
0.217758348
0.196535277
0.172524568
0.148095864
0.126298443
0.105552018
0.082646237
0.056956393
0.030427412
0.004272223
-0.020932105
-0.044105392
-0.065535744
-0.08650118
-0.108058275
-0.129718653
-0.15126788
-0.172207138
-0.192875599
-0.210721804
-0.223892954
-0.234180764
-0.24245699
-0.248751241
-0.254497463
-0.259957726
-0.263198979
-0.265028604
-0.266233953
-0.266871675
-0.267277368
-0.267508396
-0.267115148
-0.262392028
-0.249209005
-0.229932717
-0.209960915
-0.187568258
-0.162448902
-0.138449781
-0.117217126
-0.045208173
-0.045208173
-0.018919232
0.006157923
0.029908851
0.051878506
0.07289029
0.09411751
0.11610991
0.138104884
0.159062452
0.17992532
0.199691987
0.21617377
0.227494124
0.236922054
0.24445098
0.251473791
0.257960589
0.262377723
0.263954003
0.264908298
0.265840705
0.266513761
0.266883834
0.266926607
0.265419133
0.257790501
0.242526655
0.22324951
0.201531196
0.17738702
0.15342452
0.131800477
0.1109522
0.088296042
0.063498838
0.037066989
0.010316564
-0.015616037
-0.039035945
-0.060208232
-0.08085681
-0.102299178
-0.124257103
-0.146093148
-0.167006369
-0.187698005
-0.206415106
-0.221140363
-0.231744746
-0.240506058
-0.24706195
-0.252951795
-0.258685572
-0.262476571
-0.264403756
-0.265740712
-0.266647514
-0.267120155
-0.267401966
-0.267375501
-0.264605601
-0.253510696
-0.234421233
-0.214074065
-0.193235516
-0.16899335
-0.143875568
-0.12197515
-0.101470196
-0.077692375
-0.051064116
-0.024750856
0.00024519
0.024409965
0.046958977
0.067974337
0.089130174
0.111248602
0.133398358
0.154533309
0.175352976
0.195526194
0.21302035
0.225329474
0.235385398
0.243500691
0.25052765
0.25689028
0.261952861
0.26385258
0.26476353
0.265686639
0.266440233
0.266922601
0.267112573
0.266387018
0.260741789
0.24630807
0.226995877
0.207087732
0.184018586
0.158831711
0.135801045
0.115240445
0.093817531
0.068910321
0.042601209
0.016381218
-0.009371139
-0.033771233
-0.056007249
-0.076902589
-0.098074877
-0.119947257
-0.141537254
-0.162501831
-0.183455823
-0.202971006
-0.218602636
-0.229613999
-0.238881283
-0.265545304
-0.266486152
-0.267075952
-0.267396673
-0.267461475
-0.26564072
-0.256300623
-0.239229755
-0.219203594
-0.198111987
-0.17396166
-0.149193782
-0.127074924
-0.1060753
-0.083089838
-0.057333047
-0.030732969
-0.005156279
0.019082739
0.041776662
0.06321059
0.084434948
0.106116355
0.128137222
0.149638671
0.17031171
0.190921663
0.209086729
0.22252753
0.232836942
0.24125164
0.248558551
0.255367643
0.2609814
0.263386376
0.264539798
0.265508826
0.26635855
0.266895707
0.267078098
0.266581567
0.262288888
0.250137264
0.189313625
0.164919682
0.049010759
0.022428277
-0.0037179
-0.028283504
-0.050600773
-0.071547183
-0.092456543
-0.114180435
-0.136012332
-0.157430381
-0.178055069
-0.198116278
-0.215291001
-0.227322606
-0.236778288
-0.244225388
-0.250276452
-0.256240541
-0.261029608
-0.263416417
-0.265281947
-0.266418918
-0.266733631
-0.267147048
-0.267439874
-0.266462549
-0.259833415
-0.244641381
-0.223683098
-0.20293653
-0.179945776
-0.155106801
-0.131721941
-0.110566534
-0.088579999
-0.063365658
-0.036948971
-0.01102009
0.013737203
0.03681765
0.058383329
0.079424868
0.101060927
0.123067203
0.144667214
0.165688439
0.186805509

• Imagine 20% noise how you would compute zero crossing intervals Commented Feb 10, 2022 at 20:06
• RMS tells you. It's the Root of the Mean of the Squares.
– user16324
Commented Feb 10, 2022 at 20:10
• Then compare your idea with the results in this simulation by noticing the waveform and delay in half cycles before a result is ready after a reset. tinyurl.com/yamfgakp compare resolution and accuracy Commented Feb 10, 2022 at 20:15
• @user_1818839 my mind just got blown with what you said. It really did not occured to me that it was very literal. Commented Feb 10, 2022 at 20:29
• Commented Feb 10, 2022 at 21:54

Your technique may work, but will not give the exact answer if the input is not a pure sinusoid.

For RMS, you need to calculate the square root of the average of the sum of the squares -- so for each ADC reading, square it, and accumulate those values. At the (suitable) end, divide that sum-of-squares by the number of samples, and then take the square root. That is your correct RMS value.

For frequency -- if you (even roughly) know the center point of your signal, use software to determine the time of (say rising level) crossing of that. For extremely high precision, you could interpolate the time for the sample before and after that crossing. For noise immunity, then add a subsequent blanking time (say 60 % of the expected frequency if you know that), and search for the next crossing.

After N crossings, calculate frequency from the overall end and beginning time divided by N.

• Im glad that im in the right direction. It did not occur to me that RMS was very literal on what it was doing. Its one of the things that i was just taught to call it just that. For the frequency it seems to be a bit more tricky. The best way i can come up with to find the center is to average the samples( i mean that is what averaging do). Im dont quite understand how to implement the noise immunity. Can you please explain it step-by-step Commented Feb 10, 2022 at 20:46
• If you are writing software: 1) find the average; 2) search for the 1st sample that spans the average with a + slope (so sample N-1 is < avg; sample N is >= avg.); 3) record the time of that sample N; 4) (optional -- improves noise immunity) -- search for next sample say 10 % higher than SampleN; or just skip ahead to 60 % of expected Freq; 5) now search again for RISING sample M-1 & M spanning; record timeM; 6) at end you'll have X avg_crossings; 7) calculate F = X_crossings/(time of last-first sample) Commented Feb 10, 2022 at 21:23
• @jp314 Before calculating RMS value, "average" should not be known, if not well centered? Commented Feb 10, 2022 at 21:27
• Depends if it is an AC-coupled or DC-coupled signal, and if OP wants (mathematical) RMS, or just the RMS of the AC portion. The calculation above gives: RMS(above_^2 = RMS_AC^2 + DC^2. so the other parts can be calculated by calculating the average (==DC) and calculating. Commented Feb 10, 2022 at 23:01
• @jp314 Im sorry i got lost in step 4. So assuming the dataset i provided above. Step 1 is to find the average = 0.003746630189. Step 2 is to find the first number that is higher than average which is = 0.017276575 (index 61, data before this is -0.007251693). Step 3 retrieve the time when index 61 was taken lets assume for now it was 15ms from start. Step 4 is to find the first number that is 10% higher = 0.04012342 (index 62, basically the next one.). Thats basically where im at i dont understand what to do next Commented Feb 11, 2022 at 13:21