Issues on computing the square of analog read voltage by long int and unsigned long int definition

Hi, I intended to measure the voltage difference between two analogread signals (represented by anaval1 and anaval2), then compute the square of voltage and install them in the accumulated "sum" , 'Num" is to count the array index. The total length of the array is 78, when the "Num==78" the sum and Num should be 0 and start the array again. But from the serial monitor the Num keeps increasing until 90. The values from 78 to 90 all seem wrong and I don't know is it because the overflow? I wonder how to dispose the mainloop from NUM 78-90 and correct the results.

Here is my code:

long int anaval1[]={89,337,681,341,514,636,623,535,455,530,494,452,387,354,513,291,705,338,434,389,452,455,390,363,597,378,341,279,86,742,173,511,378,378,456,370,548,448,749,121,227,564,600,631,455,466,590,498,423,608,268,513,598,980,385,876,599,385,424,449,551,227,583,511,624,527,381,635,561,216,452,706,477,592,536,461,444,477};
long int anaval2[]={343,537,468,289,728,252,328,497,634,574,155,463,449,393,592,353,859,534,291,414,427,616,568,552,376,188,529,472,412,501,542,820,473,498,635,443,225,452,196,329,539,297,581,524,861,397,655,455,494,471,547,400,688,264,440,445,450,320,283,571,489,545,345,579,543,848,728,866,899,323,461,503,456,430,545,528,530,655};
unsigned long starttime;
unsigned long interval2 = 6000;  //20s
unsigned long interval1 = 3000;  //20s
long int sum;
int Num = 0;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.println(sizeof(anaval1)/sizeof(anaval1[0]));
  //pinMode(analogPin1, INPUT);
  //pinMode(analogPin2, INPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
 if ((millis() - starttime < interval2) && (millis() - starttime > interval1)) {
long int volt=anaval1[Num]-anaval2[Num];  //double volt = map(analogRead(analogPin1) - analogRead(analogPin2),0,1024,0,4.8);
   // int volt=analogRead(analogPin1) - analogRead(analogPin2);// if I use int here volt*volt is incorrect
  // but if I use long here volt*volt is incorrect
  // no matter I use long or int 

    delay(10);
    Serial.print(Num);
    Serial.print("\t");
    Serial.print(anaval1[Num]);
    Serial.print("\t");
    Serial.print(anaval2[Num]);
    Serial.print("\t");
     Serial.print(volt); 
    Serial.print("\t");
    Serial.print(volt*volt);
    Serial.print("\t");
    Serial.print(sum);
    Serial.print("\t");
    Serial.println();
    sum = sum + volt*volt;
    Num++;
  } else if (Num>=sizeof(anaval1)/sizeof(anaval1[0])) {
   
    sum = 0;
    Num = 0;
    starttime = millis();
  }
}

And this is the serial monitor data

should Num be tested immediately after being incremented?

  Num++;
 if (Num>=sizeof(anaval1)/sizeof(anaval1[0])) {

also avoid screen images - they are difficult to read and cannot be copied
copy the screen text then select < CODE/ > and paste the text where it says “type or paste code here”

your screen grab (really bad idea to post an image of text... don't ever do that again here) shows that clearly Num exceeds the size of your arrays...

The loop will spin fast and you are calculating within a large interval when you do

 if ((millis() - starttime < interval2) && (millis() - starttime > interval1)) {

Your maths should stop when reaching the end of the array.

You need to check Num inside the if

  if ((millis() - starttime < interval2) && (millis() - starttime > interval1))
  {
    long int volt = anaval1[Num] - anaval2[Num]; //double volt = map(analogRead(analogPin1) - analogRead(analogPin2),0,1024,0,4.8);
    // int volt=analogRead(analogPin1) - analogRead(analogPin2);// if I use int here volt*volt is incorrect
    // but if I use long here volt*volt is incorrect
    // no matter I use long or int

    delay(10);
    //Serial.print(millis());
    //Serial.print("\t");
    Serial.print(Num);
    Serial.print("\t");
    Serial.print(anaval1[Num]);
    Serial.print("\t");
    Serial.print(anaval2[Num]);
    Serial.print("\t");
    Serial.print(volt);
    Serial.print("\t");
    Serial.print(volt * volt);
    Serial.print("\t");
    Serial.print(sum);
    Serial.print("\t");
    Serial.println();
    sum = sum + volt * volt;
    Num++;
    if (Num >= sizeof(anaval1) / sizeof(anaval1[0]))
    {
      sum = 0;
      Num = 0;
      starttime = millis();
    }
  }

69	216	323	-107	11449	3648801	
70	452	461	-9	81	3660250	
71	706	503	203	41209	3660331	
72	477	456	21	441	3701540	
73	592	430	162	26244	3701981	
74	536	545	-9	81	3728225	
75	461	528	-67	4489	3728306	
76	444	530	-86	7396	3732795	
77	477	655	-178	31684	3740191	
0	89	343	-254	64516	0	
1	337	537	-200	40000	64516	
2	681	468	213	45369	104516	
3	341	289	52	2704	149885	
4	514	728	-214	45796	152589	

OK, thanks to all for your valuable advice. I will put the "(Num>=sizeof(anaval1)/sizeof(anaval1[0]) "inside the first if imediately after the "Num++". And I will no longer post screen snap of the serial plot again.

thanks - appreciated.

can you explain what you are trying to do with this ?

@huabridget Snaps of serial plotter are fine. But that's not what you posted!

I have a AC voltage source affected by control parameter L, each time the L changes, the AC voltage magnitude changes, but when the AC voltage reaches steady state, I want to know its voltage magnitude. So I skip the trasient period by interval 1 and use the signal when time is in between interval1 and interval2 to compute the steady state magnitude. I am still testing the algorithm. Maybe I will start another post to present the problem. The steady state of the AC voltage is a standard sinuisoidal signal. But its magnitude (cumulative(sum(magnitude)^2)/count) is not that correct if approximated according to this post. Thanks for your interest.

I assume you are looking for the RMS value
you need to take readings over several cycles adding the square of the reading to an average, e.g. where val is the ADC reading and count is the number of samples

ave=ave+(val*val);    
count++;

after a number of cycles calculate the RMS

float rms = sqrt(ave/count);

generally microcontroller ADCs read positive voltages only so any AC input will need to be offset

have a look at PZEM-004T V3.0 measure the voltage, current, power, etc

Many thanks. Pzem004t seems appropriate for AC voltage 127/220V. But in my case, the ac voltage magnitude is about 15V, i.e., 30V P2P. And the frequency is from 0.3-1Hz. I am actually thinking about using the circuit from this post https://simple-circuit.com/measure-ac-voltage-arduino-ac-voltmeter/. Will update if it works.

for 15V AC I would think a simple voltage divider plus a DC offset would do?

what host microcontroller are you using?

for such a low frequency I think you would need to sample over 20 or 30 seconds - say 200 samples/second
you need to experiment - have you an oscilloscope?