Author Topic: Homebrew Lock-In Amplifier  (Read 10123 times)

0 Members and 1 Guest are viewing this topic.

Offline PicuinoTopic starter

  • Frequent Contributor
  • **
  • Posts: 956
  • Country: 00
    • Picuino web
Re: Homebrew Lock-In Amplifier
« Reply #150 on: May 13, 2024, 05:08:30 pm »
EDIT: And I wonder which kind of modulation the vibrations of the glass apply to to the excitation signal. Really AM? Isn't rather time of flight modulated, resulting in FM (Doppler effect)?

With the low frequency of sound and the associated low velocity of motion, the doppler shift would be almost impossible to detect. I am sure that in this case what needs to be detected is AM modulation.
 

Offline PicuinoTopic starter

  • Frequent Contributor
  • **
  • Posts: 956
  • Country: 00
    • Picuino web
Re: Homebrew Lock-In Amplifier
« Reply #151 on: May 13, 2024, 05:12:07 pm »
I have to study the detector. In principle I am going to use a simple infrared led as detector and another infrared led (the same type of led) with output through a couple of small holes in series to collimate the light beam.

A laser would be more efficient and collimated, but I don't have one and I'm a little afraid to work with infrared lasers.

As I am going to test with a small crystal on my own table, I don't think there will be any problems.
 

Offline PicuinoTopic starter

  • Frequent Contributor
  • **
  • Posts: 956
  • Country: 00
    • Picuino web
Re: Homebrew Lock-In Amplifier
« Reply #152 on: May 13, 2024, 06:46:30 pm »
I had forgotten something regarding the multiplicator optimization: The optimization should not be limited to an ordinary sine wave, but it should consider a complex sine wave (i.e. both, cos and sin components together). Here is an update.

Code: [Select]

nsamples = 16;

x = repmat(exp(-1j*[0:nsamples-1]/nsamples*2*pi)',1,127);
y = zeros(nsamples,127);
for i=1:127
  % quantize to 2*i+1 levels
  y(:,i) = floor(0.5+0.5i+x(:,i)*i)/i;
end

Y = zeros(nsamples,127);
for i=1:127
  Y(:,i) = fft(y(:,i))/nsamples;
end

P = abs(Y).**2;
Pfund = P(2,:);
harmidx = [ 1 3:nsamples ];
Pharm = sum(P(harmidx,:));
Pspur = max(P(harmidx,:));

plot(10*log10(Pharm./Pfund),";THD;");
hold on
plot(10*log10(Pspur./Pfund),";SFDR;");
title(sprintf("%d samples/period",nsamples))
grid on
hold off
ylabel("dB")
xlim([20 127])
ylim([-65 -30])



I have installed Octave and I can't see the graphs.
This is the error I get:
Code: [Select]
>> sin_integer

error: parse error near line 15 of file C:\Users\User\sin_integer.m

  syntax error

>>> P = abs(Y).**2;
                ^
>>
 

Offline gf

  • Super Contributor
  • ***
  • Posts: 1292
  • Country: de
Re: Homebrew Lock-In Amplifier
« Reply #153 on: May 13, 2024, 07:47:53 pm »
error: parse error near line 15 of file C:\Users\User\sin_integer.m

  syntax error

>>> P = abs(Y).**2;

I'm running an older version of Octave.
Seems that operator .** was deprecated in the meantime?
https://savannah.gnu.org/bugs/?60882
Try .^ instead.

I also noticed that you don't place the first sample at phase 0, but at pi/SAMPLES_PER_PERIOD.
I have updated the script accordingly.

Code: [Select]

nsamples = 16;
MAXMUL = 127;

% sampling phase = 0
% x = repmat(exp(-1j*[0:nsamples-1]/nsamples*2*pi)',1,MAXMUL);

% sampling phase = pi/nsamples
x = repmat(exp(-1j*[0:2*nsamples-1]/2/nsamples*2*pi)(2:2:end)',1,MAXMUL);

y = zeros(nsamples,MAXMUL);
for i=1:MAXMUL
  % quantize to 2*i+1 levels
  y(:,i) = floor(0.5+0.5i+x(:,i)*i)/i;
end

Y = zeros(nsamples,MAXMUL);
for i=1:MAXMUL
  Y(:,i) = fft(y(:,i))/nsamples;
end

P = abs(Y).^2;
Pfund = P(2,:);
harmidx = [ 1 3:nsamples ];
Pharm = sum(P(harmidx,:));
Pspur = max(P(harmidx,:));

plot(10*log10(Pharm./Pfund),";THD;");
hold on
plot(10*log10(Pspur./Pfund),";SFDR;");
title(sprintf("%d samples/period",nsamples))
grid on
hold off
ylabel("dB")
xlim([20 MAXMUL])
ylim([-65 -30])

 

Offline PicuinoTopic starter

  • Frequent Contributor
  • **
  • Posts: 956
  • Country: 00
    • Picuino web
Re: Homebrew Lock-In Amplifier
« Reply #154 on: May 13, 2024, 08:22:20 pm »
Now it works.
I have seen that the best (low) multiplier is 61.


 

Offline PicuinoTopic starter

  • Frequent Contributor
  • **
  • Posts: 956
  • Country: 00
    • Picuino web
Re: Homebrew Lock-In Amplifier
« Reply #155 on: May 13, 2024, 08:23:15 pm »
I'm going to copy the script in the other thread, with your permission.
 

Offline gf

  • Super Contributor
  • ***
  • Posts: 1292
  • Country: de
Re: Homebrew Lock-In Amplifier
« Reply #156 on: May 13, 2024, 08:25:05 pm »
Now it works.
I have seen that the best (low) multiplier is 61.

At least the best one below 64 (which is only imporant if you still want to optimize the multiplication performance).
 

Offline PicuinoTopic starter

  • Frequent Contributor
  • **
  • Posts: 956
  • Country: 00
    • Picuino web
Re: Homebrew Lock-In Amplifier
« Reply #157 on: May 17, 2024, 05:33:40 pm »
I already have the STM32 microcontroller sampling the ADC at 5333kHz.
The problem I have now is the large computational power needed to multiply two streams from the two ADCs at more than 5MHz in real time and implement, in addition, an IIR or FIR filter for the output.
And all that for the microprocessor to do the same as a simple AD630, but worse.

I think you should start with a much lower ADC speed and go up from there.
I would also have to be clear about extra functions that the microcontroller is capable of to justify its use.
 

Offline Kleinstein

  • Super Contributor
  • ***
  • Posts: 14348
  • Country: de
Re: Homebrew Lock-In Amplifier
« Reply #158 on: May 17, 2024, 06:11:53 pm »
Usually one does not want an exact copy of the ref. signal to do the multiplication. One usually wants at least a constant amplitude for the reference signal.
The operation of the AD630 is different: it only does a +-1 multiplication, not a true multiplication. The multiplication with a clean sine can suppress the other harmonics.


To reduce the computational effort one can initially apply a little low pass filtering, kind of part of the anti aliasing. Even just averaging 2 readings can reduce the computational effort to nearly half.
It can make sense to run the ADC at a little less than it's maximum speed. The max speed is kind of set by the noise / INL starting to get worse from there.
 

Offline PicuinoTopic starter

  • Frequent Contributor
  • **
  • Posts: 956
  • Country: 00
    • Picuino web
Re: Homebrew Lock-In Amplifier
« Reply #159 on: May 18, 2024, 10:04:37 am »
I didn't realize that the STM32 board I am currently using (NUCLEO-L412KB) does not have a DAC.
I have placed an order for another board, a NUCLEO-G431KB, which runs at more than twice the speed (170MHz) and has 2 ADCs and 2 buffered DACs.
With them I can generate a reference output signal (1 DAC) and sample two signals, the reference output signal and the one coming from the DUT.


By the way I have also bought some instrumentation amplifiers INA826 from Texas Instruments, which work at 3.3V although they are a bit slow.
For further amplification I have bought precision opamps OPA2325, also from Texas Instruments.

EDIT:
https://www.st.com/resource/en/datasheet/stm32g431kb.pdf
https://www.ti.com/lit/ds/symlink/ina826.pdf
https://www.ti.com/lit/ds/symlink/opa2325.pdf


Other amplifiers that I have not purchased, but should consider (recommended by TI):
https://www.ti.com/lit/ds/symlink/ina333.pdf
https://www.ti.com/lit/ds/symlink/opa322.pdf
https://www.ti.com/lit/ds/symlink/opa320.pdf
https://www.ti.com/lit/po/sbat003a/sbat003a.pdf
« Last Edit: May 19, 2024, 11:02:57 am by Picuino »
 

Offline gf

  • Super Contributor
  • ***
  • Posts: 1292
  • Country: de
Re: Homebrew Lock-In Amplifier
« Reply #160 on: May 18, 2024, 11:46:11 am »
The problem I have now is the large computational power needed to multiply two streams...

The multiplication is not the problem. AFAIK, the SMLAL instruction takes only one cycle. And gcc does recognize the pattern

Code: [Select]
int64_t c;
int32_t a, b;
c += (int64_t)a * b;

and emits a SMLAL instruction. The problem is more the necessary glue code to shuffle the data around.

Note that the clock frequency is only 5x higher than the clock frequency of your AVR, but you want a 500x higher data rate. And now you expect that the more efficient instruction set of the ARM processor can compensate the remaining gap of factor 100x? No, it cannot.

Nevertheless I think that it may be feasible to run the algorithm of your Milliohm meter (single channel) at 4 MSa/s, if you do it smart. Collect the samples with double buffered DMA, and process all samples in a received DMA buffer at once. At that speed it is no longer possible to process an interrupt for each sample. That's ways too much overhead per sample.

If you look here, you can see that the innermost loop (label .L2, which is executed for each sample) has 11 instructions, and I think that's 14...17 clock cycles, and the code outside the loop (which uses significantly more cycles) runs only once for 256 samples, so let's assume ~1 extra cycle per sample. At 80 MHz clock and 4 MSa/s, you can spend 20 cycles/sample. So I think that's in the ballpark.

And if you decimate before demodulation (see here), as Kleinstein suggested, then the overhead per sample becomes even smaller. Here, the loop at label .L2 now processes 8 samples at each iteration.

Quote
I have placed an order for another board, a NUCLEO-G431KB, which runs at more than twice the speed (170MHz) and has 2 ADCs and 2 DACs.

I'm unsure if the amount of RAM is sufficient. It depends of course on the exact algorithms you want to run at the end. It may be possible to put constant tables in flash, but I'm not sure if data access to flash also has zero wait states.



Btw, see also:
https://wiki.st.com/stm32mcu/wiki/Getting_started_with_ADC
https://www.st.com/resource/en/application_note/an2834-how-to-optimize-the-adc-accuracy-in-the-stm32-mcus-stmicroelectronics.pdf
 

Offline PicuinoTopic starter

  • Frequent Contributor
  • **
  • Posts: 956
  • Country: 00
    • Picuino web
Re: Homebrew Lock-In Amplifier
« Reply #161 on: May 18, 2024, 12:09:28 pm »
In this case I want to make a more generic Lock-in amplifier.
The routine I am thinking of is something like this:
* Fill with DMA two 256-sample (16bit type) buffers coming from the two ADCs.
* With the half-transfer buffer interrupt, multiply the two half buffers into another (32bit type) half mult-buffer.
* With the full-transfer buffer interrupt, do the same with the other half of the buffer.
* With another timer interrupt, sum all the mult-buffer values and pass them through an IIR filter to deliver the value to the DAC output.

The result should do, by software, the same as an AD630 plus a low-pass filter.
 

Offline PicuinoTopic starter

  • Frequent Contributor
  • **
  • Posts: 956
  • Country: 00
    • Picuino web
Re: Homebrew Lock-In Amplifier
« Reply #162 on: May 18, 2024, 12:16:54 pm »
Analog Devices has a chip for digital synchronous detection, the ADA2200, which is now obsolete.
https://www.analog.com/media/en/technical-documentation/data-sheets/ADA2200.pdf

It may be interesting to study it.
 

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2246
  • Country: pr
Re: Homebrew Lock-In Amplifier
« Reply #163 on: May 18, 2024, 09:30:04 pm »
This very much sounds like a problem for an fpga.  You won't be constrained by the processing speed of your CPU, and you can make the multipliers work with any data size you wish.  You will need to learn a new language.  More importantly, you will need to learn to think in terms of a multiprocessing language.  In fpgas, everything happens in parallel, or much of it, anyway. 
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 

Offline PicuinoTopic starter

  • Frequent Contributor
  • **
  • Posts: 956
  • Country: 00
    • Picuino web
Re: Homebrew Lock-In Amplifier
« Reply #164 on: May 19, 2024, 07:22:10 am »
I have two FPGA development boards. A Cyclone II and an Alhambra Zum, but I have never run them.

Keep in mind that my intention is to make a homebrew lock-in amp and working with FPGAs doesn't seem very compatible. I would need to add external ADCs with parallel connections, which would probably involve designing a dedicated PCB and soldering components with difficult encapsulations. It would have a lot of power, but it certainly wouldn't be homebrew.

In the world of microcontrollers there are all kinds of models from the most basic 8-bit to the most powerful 32-bit models. There are options from THT and also SMD packages with easy to solder pins, to the smallest and most difficult.
In the FPGA world, however, I don't see models in between. All I find are unwieldy models for home assembly.
 

Offline Kleinstein

  • Super Contributor
  • ***
  • Posts: 14348
  • Country: de
Re: Homebrew Lock-In Amplifier
« Reply #165 on: May 19, 2024, 08:10:00 am »
For a simple solution the µC with 12 bit ADCs is ok. The computation power should not be that much of an issue. After all even with 2x5 MSPS the CPU should still be able to keep up. It should not be much more than 1 MAC operation and 1 table lookup per sample.  The speed would mainly effect the upper frequency limit and many application for a lock-in amplifier are lower frequency, like 100 Hz-1 kHz.
There is also the alternative way of first average the time domain data and do the muliplication with the sine (or other function for correlation) only at the lower output rate.

The more limiting factor is more the resolution of the ADC, so that the headroom for noise is limited. It can be OK for not so noisy signals, but one application for a lock-in amplifier is with signals that are burried in a lot of noise. AFAIR the lock in amplifier I use a lot had settings for the headroom of 40 and 60 dB. So in the higher reserve setting the signal would be something like 1000 times smaller than the input dynamic range.  So an external ADC would not be such a bad idea for a higher performance lockin. It could still make sense to use a µC with an external ADC.

The computational more demanding case could be if one wants a really external reference and thus a PLL for the reference part. A software PLL is possible and has some advantages over a hardware solution as it is easier to adapt over a large frequency range (e.g. changing the loop filter).

 

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2246
  • Country: pr
Re: Homebrew Lock-In Amplifier
« Reply #166 on: May 19, 2024, 09:14:22 am »
I have two FPGA development boards. A Cyclone II and an Alhambra Zum, but I have never run them.

Keep in mind that my intention is to make a homebrew lock-in amp and working with FPGAs doesn't seem very compatible. I would need to add external ADCs with parallel connections, which would probably involve designing a dedicated PCB and soldering components with difficult encapsulations. It would have a lot of power, but it certainly wouldn't be homebrew.

In the world of microcontrollers there are all kinds of models from the most basic 8-bit to the most powerful 32-bit models. There are options from THT and also SMD packages with easy to solder pins, to the smallest and most difficult.
In the FPGA world, however, I don't see models in between. All I find are unwieldy models for home assembly.

fpgas are available in quad flat packs, often 100 pin.  You can fashion DAC by using a very fast clock and generating a pulse train with a high speed clock.  The modulation would be pulse density and use a simple RC filter to remove the higher frequency artifacts.  If you need limited resolution, but higher sample rates, you can use multiple output pins with an R/2R ladder.  N bits uses N output lines.

ADC is similar, but the effective sample rate would need to be moderately low.  There's a sample rate/resolution trade off.  15 bits at 48 kSPS is realistic using a clock rate of ~32 MHz (if I remember the math correctly).  I'm not sure what sample rates you require.  An effective sample rate above 100 kSPS would likely need a separate ADC chip. 

I will say, I don't know what you mean by "homebrew".  Can you explain what this means to you? 
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 

Offline PicuinoTopic starter

  • Frequent Contributor
  • **
  • Posts: 956
  • Country: 00
    • Picuino web
Re: Homebrew Lock-In Amplifier
« Reply #167 on: May 19, 2024, 10:22:20 am »
For example the other experiment I have done I consider it homebrew.
It uses an Arduino Nano as microcontroller (Atmega328P) easy to get and easy to program. As analog part I have used 8-pin SMD chips (MSOP-8) that can be soldered with soldering iron (no hot air station needed). I will also test an INA826, much cheaper than AD8220 and with an even simpler package (SOIC-8).

I consider FPGAs far from a homebrew project for now.

In any case, I have achieved acceptable results with a simple Atmega328 at 16MHz and with 10bits ADC at 10ksps ADC. With the STM32 I should be able to get something practical and better (170MHz and 12bit ADC at 5Msps).
 

Offline gf

  • Super Contributor
  • ***
  • Posts: 1292
  • Country: de
Re: Homebrew Lock-In Amplifier
« Reply #168 on: May 19, 2024, 10:29:31 am »
There is also the alternative way of first average the time domain data and do the muliplication with the sine (or other function for correlation) only at the lower output rate.

Some STM32 models (including the STM32L412xx) have a hardware oversampler that does exactly this, so you can benefit from the resolution enhancement and SNR reduction without overstraining the DSP code with too high a sample rate.

 

Offline PicuinoTopic starter

  • Frequent Contributor
  • **
  • Posts: 956
  • Country: 00
    • Picuino web
Re: Homebrew Lock-In Amplifier
« Reply #169 on: May 19, 2024, 10:44:32 am »
I'm actually going to switch microcontroller to an STM32G431KB, which does have DACs and runs at double CPU speed.
This other micro also has that function, which I will study to see if it is useful. The problem is that I wanted to be able to sample 100kHz signals with several samples and that is difficult to do below 1Msps.
That microcontroller I want to run at 160MHz and the ADC clock speed at 80MHz (1/2), which produces 5333Msps.

Maybe there is enough speed left to decimate 4 samples in one and reduce the sampling speed to 1.33Msps.
 

Offline gnuarm

  • Super Contributor
  • ***
  • Posts: 2246
  • Country: pr
Re: Homebrew Lock-In Amplifier
« Reply #170 on: May 19, 2024, 10:51:51 am »
For example the other experiment I have done I consider it homebrew.
It uses an Arduino Nano as microcontroller (Atmega328P) easy to get and easy to program. As analog part I have used 8-pin SMD chips (MSOP-8) that can be soldered with soldering iron (no hot air station needed). I will also test an INA826, much cheaper than AD8220 and with an even simpler package (SOIC-8).

I consider FPGAs far from a homebrew project for now.

In any case, I have achieved acceptable results with a simple Atmega328 at 16MHz and with 10bits ADC at 10ksps ADC. With the STM32 I should be able to get something practical and better (170MHz and 12bit ADC at 5Msps).

Sorry, I have no idea why an MCU board bought off the Internet is "homebrew" and an fpga board bought off the Internet is not homebrew. 

As to the MCU with ADCs, remember that when run at high sample rates, the lower one or two bits are essentially "noise".  Sounds like you don't really know what you need and are just toying around trying to get something to work.  Good luck.
Rick C.  --  Puerto Rico is not a country... It's part of the USA
  - Get 1,000 miles of free Supercharging
  - Tesla referral code - https://ts.la/richard11209
 

Offline PicuinoTopic starter

  • Frequent Contributor
  • **
  • Posts: 956
  • Country: 00
    • Picuino web
Re: Homebrew Lock-In Amplifier
« Reply #171 on: May 19, 2024, 11:24:25 am »
Yes, I am playing with the STM32 with two targets. To know how to use it (I had not implemented it before) and to make with that microcontroller a Lock-in amplifier that is able to do something practical.
It is not a job where I have to achieve a certain goal. I am a Technology teacher and I just try to keep up to date myself and make some practical instrument for demonstrations in class.


EDIT:
I don't rule out running one of my FPGA boards or another more modern one. But I have to go in parts. For now I'm too busy with the STM32.
« Last Edit: May 19, 2024, 11:27:23 am by Picuino »
 

Offline PicuinoTopic starter

  • Frequent Contributor
  • **
  • Posts: 956
  • Country: 00
    • Picuino web
Re: Homebrew Lock-In Amplifier
« Reply #172 on: May 19, 2024, 11:59:10 am »
Of course, another goal is to make easy replicable projects by anyone else. FPGAs is a little bit more difficult than uC.
 

Offline gf

  • Super Contributor
  • ***
  • Posts: 1292
  • Country: de
Re: Homebrew Lock-In Amplifier
« Reply #173 on: May 19, 2024, 12:23:42 pm »
Maybe there is enough speed left to decimate 4 samples in one and reduce the sampling speed to 1.33Msps.

The hardware oversampler can do this without any software overhead. It samples at 5.33 MSa/s and delivers decimated samples at 1.33 MSa/s to the processor. However, the summation of 4 samples each corresponds to a 1st order boxcar filter, and that's not a proper decimation filter. This implies that the (analog) anti-aliasing filter in front of the ADC must be steeper in order to provide sufficient attenuation for frequencies >= 1233 kHz (unless you can ensure otherwise that no interfering signals >= 1233 kHz are present at the ADC input). For example, a 4th order Butterworth with fc=160kHz gives >70dB attenuation for frequencies >= 1233 kHz, while 100kHz still fall into the passband, being attenuated only about 0.1dB.
« Last Edit: May 19, 2024, 12:29:01 pm by gf »
 

Offline Kleinstein

  • Super Contributor
  • ***
  • Posts: 14348
  • Country: de
Re: Homebrew Lock-In Amplifier
« Reply #174 on: May 19, 2024, 01:06:21 pm »
An anti aliasing filter is a good idea with a SAR or similar ADC. The main reason would be avoiding extra noise, not so much a strong interference signal. For the noise suppresion there is no need for the AA fitler to get very strong attenuation, just 20 dB already do a lot for the noise.  A strong interference is often more an issue at low frequencies, with mains hum and the 2nd harmonic.
Especially with the limited ADC resolution filtering at the low end or notches can make sense.

Averaging 4 samples is not a perfect filter, but it is still not that bad compared to a more conventional digital filter.

Using a similar sampling and math also on the ref. channel is an unusual solution for a lock-in amplifier. It could be a first step to do a software PLL, though for the ref. side a simple on/off digital input is often sufficient.
Digitizing 2 inputs and directly multiply and average would be part of getting the cross-correlation function. This is related to a LI and may be an interesting addition, but it is not the normal LI function.

Many on the articles decribing LI operation are a bit short on the reference part and often asume quite some ideallization there. For the ref. side there are different cases, depending on the experiment / setup:
1) generate the ref. / driving signal - this is the easiest case
2) generate the ref. frequency and PLL drive a chopper: the PLL / regulator part could be external
3) read an external ref signal and use it directly for the PSD / detection. This may need a way to correct for duty cycle changes
4) read an external ref signal and use a PLL to generate a clean ref. signal for the PSD.
5) read an external ref signal and use a PLL to generate a clean ref., with a delay for the input data to compensate for the group delay of the PLL

There are cases where one would read a 2nd signal, e.g. to compensate for intesity variations of a light source. The 2nd channel tends to be less demanding, with often a better S/N ratio. The amplitude ref. is however often separate from a frequency/phase reference.

 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf