Analog Filter with Gain and Subtraction
The Quarto can be used to filter analog signals. In this tutorial, we will take two analog inputs, , and and create a new output defined by the following equation:
Finally, we will low-pass filter this signal with a cut-off frequency of 10 kHz. We will output the unfiltered signal on DAC channel 1 and the filtered signal on DAC channel 2.
Setup
We will fully utilize the 1 mega-sample per second (MS/s) capability of the Quarto and have it measure two analog channels at 500 kHz each. This means each channel will make a measurement every 2 µs. That is configured in the setup function:
void setup() {
configureADC(1,2,0,BIPOLAR_5V,getADC1); // Have ADC1 take measurement every 2 µs, ±5 V range
configureADC(2,2,1,BIPOLAR_5V,getADC2); // Have ADC2 take measurement every 2 µs, ±5 V range
}
In this case, both ADC channels are set to the ±5 V range.
Main Functions
When ADC1 gets its measurement, we need to wait until ADC2 gets its measurement as well before we can proceed, so we will just store the result in a global variable adc1 . Then when ADC2 gets its measurement, we can do the subtraction and amplification. So the two callback functions getADC1 and getADC2 that we configured in the setup will become:
double adc1; // global to store latest adc1 value
double b = 1.15; // scaling on the second channel
double c = 3.75; // scaling on subtracted signal
void getADC1() {
adc1 = readADC1_from_ISR(); //store ADC1 voltage measurement
}
void getADC2() {
double adc2 = readADC2_from_ISR(); //store ADC2 voltage measurement
double pre_filter = (adc1 - adc2 * a ) * b;
writeDAC(1,pre_filter); //write value to DAC1
}
Now we have implemented as defined above by doing a weighted subtraction between ADC channel 1 and channel 2 and then multiplying the result by b. The next step is to apply the low-pass filter to this result.
The Digital Filter
Digital filtering is a complex topic, and this example is only going to give an intuitive explanation and will not go into the theory. For reference, the filter we are implementing is a first-order infinite impulse filter (IIR) and we will use it to approximate a first-order analog R-C filter.
To low-pass filter the signal, we want to stop it from changing too quickly, and to do this we want to limit how much a new ADC measurement can affect the output. The simplest way to do this is have:
where is between 0 (exclusive) and 1. The smaller is, the less influenced the Output is by the Input. The problem with this is that while the is less influenced from fast changes in the , it is also less influenced by all changes from the , regardless of the frequency of that change. We want a unity filter where for slow signals, the equals the , so we need to add back the low-frequency gain lost from the attenuation caused by . We will add this gain back by adding a term that anchors the to its previous value, .
Now when the Input suddenly changes, the will only change by an amount set by the factor . That increase, however, will cause the to increase, which will then cause to increase. Which will cause to increase. Which will cause to increase, and so on and so on. To determine the final (or steady-state) value of , we set = since is no longer changing. Then the above equation becomes