As long as we're talking about using other chips/platforms...
The STM32F4 series (Arduino Black Pill, Blue Pill etc.) has high speed 12-bit ADC with automatic channel switching. You can configure it to alternately read channel 0 & channel 1, and put the data directly into RAM using DMA at up to 1.5microseconds/ 12-bit sample. Number of samples is only limited by the amount of RAM you have available.
Just throwing that out there...
That said, while I know the chip has the capability, I don't know if the Arduino platform offers support for DMA and this particular configuration mode so depending on programmer ability, it could take a while to get this working.
the following uses an Arduino Due
timer interrupts every 20uSec and samples A0 and A1 which are stored in a array of 10000 samples - when arrays are full samples are printed to Serial
// Arduino Due ADC using timer interrupts
// timer interrupts every 20uSec and samples A0 and A1
// data stored in array of 10000 samples
// when arrays are full samples are printed to Serial
#include <DueTimer.h>
// A0 and A1 data array
#define SAMPLES 10000
volatile int data1[SAMPLES] = { 0 };
volatile int index1 = 0;
volatile int data2[SAMPLES] = { 0 };
volatile int index2 = 0;
volatile int counter = 0;
// called on timer interrupt - read ADCs
void myTimerHandler() {
counter++;
//index1=index2=0; // used for testing timer
if (index1 < SAMPLES) {
data1[index1++] = analogRead(A0);
data2[index2++] = analogRead(A1);
}
}
void setup() {
Serial.begin(115200);
//Serial.println("\nArduino Due ADC A0");
Timer3.attachInterrupt(myTimerHandler);
Timer3.start(20); // interrupt every 20uSec
}
void loop() {
// print number of samples/second
static long timer2 = millis();
if (millis() - timer2 >= 1000) {
// Serial.print("Counter ");
// Serial.println(counter);
timer2 = millis();
counter = 0;
}
//return;
static long timer1 = millis();
// if arrays are full print contents
if (index1 == SAMPLES) {
Timer3.detachInterrupt();
/* Serial.print("time to sample "); Serial.print(millis()-timer1);
Serial.print("mSec\nCounter ");
Serial.println(counter);
Serial.print("sample/sec ");
Serial.println(1.0 / (float(counter) * 20.0e-6 / SAMPLES));
*/
for (int i = 0; i < 500; i += 1) { // print frist 500 samples
// print every 20th sample in arrays
// for (int i = 0; i < SAMPLES; i += 20) {
Serial.print(data1[i]);
Serial.print(' ');
Serial.println(data2[i]);
}
index1++;
}
}
this shows the first 500 samples both signals in phase
added simple calculation of frequency and phase difference
void loop() {
// print number of samples/second
static long timer2 = millis();
if (millis() - timer2 >= 1000) {
// Serial.print("Counter ");
// Serial.println(counter);
timer2 = millis();
counter = 0;
}
//return;
static long timer1 = millis();
// if arrays are full print contents
if (index1 == SAMPLES) {
Timer3.detachInterrupt();
Serial.print("time to sample ");
Serial.print(millis() - timer1);
Serial.print("mSec\nCounter ");
Serial.println(counter);
Serial.print("sample/sec ");
Serial.println(1.0 / (float(counter) * 20.0e-6 / SAMPLES));
//for (int i = 0; i < 500; i += 1) { // print frist 500 samples
// print every 20th sample in arrays
for (int i = 0; i < SAMPLES; i += 20) {
Serial.print(data1[i]);
Serial.print(' ');
Serial.println(data2[i]);
}
index1++;
// calculate period and frequency
int zeroIndex = 0, zeroAverage = 0, counter = 0;
float freqAverage = 0.0, phaseAverage = 0.0;
;
for (int i = 200; i < SAMPLES-200; i++) {
if (signbit(data1[i + 1] - 400) != signbit(data1[i] - 400)) {
Serial.print("zero cross ");
Serial.print(i);
if (zeroIndex) {
zeroAverage += (i - zeroIndex);
counter++;
Serial.print(" Period ");
Serial.print((i - zeroIndex) * .020 * 2);
Serial.print(" frequency ");
Serial.println(1000.0 / ((i - zeroIndex) * .020 * 2));
freqAverage += (1000.0 / ((i - zeroIndex) * .020 * 2));
}
zeroIndex = i;
}
}
zeroAverage /= counter;
Serial.print("zeroAverage ");
Serial.println(zeroAverage);
Serial.print("average frequency ");
float aveFrequency=freqAverage / counter;
Serial.println(aveFrequency);
counter = 0;
zeroIndex = 0;
for (int i = 200; i < SAMPLES-200; i++) {
if (signbit(data1[i + 1] - 400) != signbit(data1[i] - 400)) {
Serial.print("data zero cross ");
Serial.print(i);
zeroIndex = i;
}
if (signbit(data2[i + 1] - 400) != signbit(data2[i] - 400)) {
Serial.print(" data1 zero cross ");
Serial.print(i);
if (zeroIndex) {
Serial.print(" phase ");
Serial.print(i - zeroIndex);
Serial.print(" ");
Serial.println(180 * float(i - zeroIndex) / zeroAverage);
phaseAverage += (180 * float(i - zeroIndex) / zeroAverage);
counter++;
//Serial.println(1000.0 / ((i - zeroIndex) * .250 * 2));
}
zeroIndex = i;
}
}
Serial.print("\naverage frequency ");
Serial.println(aveFrequency);
Serial.print("average phase difference ");
Serial.println(phaseAverage / counter);
}
}
some results
in phase
average frequency 50.01
average phase difference 88.42
average frequency 50.01
average phase difference 88.36
average frequency 50.01
average phase difference 88.34
2 degrees
average frequency 50.01
average phase difference 1.88
average frequency 50.01
average phase difference 1.99
average frequency 49.98
average phase difference 1.91
5
average frequency 50.04
average phase difference 4.96
average frequency 49.98
average phase difference 5.00
average frequency 50.01
average phase difference 4.75
10
average frequency 50.01
average phase difference 9.12
average frequency 50.03
average phase difference 10.05
average frequency 50.01
average phase difference 10.02
20
average frequency 2545.03
average phase difference 22.32
average frequency 49.98
average phase difference 19.89
average frequency 50.01
average phase difference 18.17
40
average frequency 50.01
average phase difference 39.85
average frequency 50.01
average phase difference 40.02
average frequency 50.01
average phase difference 40.00
60degrees
average frequency 50.01
average phase difference 59.89
average frequency 49.97
average phase difference 59.89
average frequency 50.01
average phase difference 60.04
80drgrees
average frequency 50.01
average phase difference 80.02
average frequency 50.01
average phase difference 80.02
average frequency 50.01
average phase difference 80.07
110
average frequency 50.01
average phase difference 109.93
average frequency 49.98
average phase difference 109.93
average frequency 50.01
average phase difference 110.24
130
average frequency 49.98
average phase difference 129.90
average frequency 50.01
average phase difference 130.00
average frequency 50.01
average phase difference 129.98
160
average frequency 50.00
average phase difference 159.96
average frequency 50.00
average phase difference 160.08
average frequency 50.01
average phase difference 159.88
below 2 degrees phase difference results are inconsistent
clearly more work required on algorithms
e.g. could upload raw data to a PC and use Matlab to do the calculations
you would need to get the current and voltage signals into a range 0 to 3volts suitable for the Due ADCs then try the code and see if it gives satisfactory results
if it does not
increase the samples/second by using ADC DMA
improvie the phase difference detection algorithm
I worked on a similar system a few years ago detecting the phase difference between a pair of signals between 1 and 10MHz - blocks of data were sampled and sent over Ethernet to a PC where Matlab was used to determine phase difference.
the data acquisition system used Texas DSP processors each costing about £5K