For the sampling of data, I would use a "timer interrupt" for "exact" regularity.
Then calculate outside interrupt ... P, E, and others variables if needed ... as fast as possible within "time" ...
Here a sample of parts program/libraries used with Arduino UNO...
- digitalWrite(13, HIGH) ; digitalWrite(13, LOW) ;
are for tracing on "logic analyser" the timings of sample ...
Program was use for tracing power & energy on just one 20ms cycle period (21 samples), repeated as soon as possible after all calculations (FFT included).
#include <TimerOne.h>
#include <LowPower.h>
void setup()
{
Serial.begin(115200); // Open serial connection to report values to host
pinMode(13, OUTPUT);
Timer1.initialize(1000); // set a timer of length 1000 microseconds
Timer1.attachInterrupt( timerIsr ); // attach the service routine here
}
/// --------------------------
/// Custom ISR Timer Routine
/// --------------------------
void timerIsr()
{
if (count < nbp)
{
// Start ADC on negative edge of D13 8 channels ??? in 1 ms ??? OK !!!
// Serial.print(micros() / 10000); Serial.print("/");
// Serial.print(micros() % 10000); Serial.print("/"); // 4 us d'erreur max
// delays are used for some corrections when calculating all powers S, P, Q
digitalWrite(13, HIGH) ; delayMicroseconds(1); digitalWrite(13, LOW) ; // 0 us
sensorValue0[count] = analogRead(A0) ;
digitalWrite(13, HIGH) ; delayMicroseconds(1); digitalWrite(13, LOW) ; // 124 us
sensorValue1[count] = analogRead(A1) ;
digitalWrite(13, HIGH) ; delayMicroseconds(1); digitalWrite(13, LOW) ; // 243.5 us
sensorValue2[count] = analogRead(A2) ;
digitalWrite(13, HIGH) ; delayMicroseconds(1); digitalWrite(13, LOW) ; // 358.5 us
sensorValue3[count] = analogRead(A3) ;
digitalWrite(13, HIGH) ; delayMicroseconds(1); digitalWrite(13, LOW) ; // 479 us
sensorValue4[count] = analogRead(A4) ;
digitalWrite(13, HIGH) ; delayMicroseconds(1); digitalWrite(13, LOW) ; // 599 us
sensorValue5[count] = analogRead(A5) ;
digitalWrite(13, HIGH) ; delayMicroseconds(1); digitalWrite(13, LOW) ; // 715 us
sensorValue6[count] = analogRead(A6) ; // mid point
digitalWrite(13, HIGH) ; delayMicroseconds(1); digitalWrite(13, LOW) ; // 838.5 us
sensorValue7[count] = analogRead(A7) ; // mid point
digitalWrite(13, HIGH) ; delayMicroseconds(1); digitalWrite(13, LOW) ; // 963.5us end
// ADC channels A4, A5, A6, A7 are also ok ... on pro/mini boards ...
// channel ... for tension measured at the "same time" ... 20.005 ms ok
// then ... calculus of active/reactive/apparent power possible
// by formula active power = v(0)*c(0)+v(90)/c(90) ???
// Serial.print(micros()); Serial.print(" / ");
// for control exact timing
}
else {
Timer1.stop();
digitalWrite(13, LOW) ;
num_per++ ;
}
count++ ;
}
```