Lock-in Amplifier - Analog or Digital?

by OptikGeek in Circuits > Electronics

304 Views, 2 Favorites, 0 Comments

Lock-in Amplifier - Analog or Digital?

lockinInstrument.png

The Lock-in Amplifier, aka synchronous detector, is an effective way to detect low-level electronic signals in the presence of interference and noise. Here we briefly describe the theory, using as an example an optical beam detector, and then detail an analog implementation and a minimalist Arduino version.

Supplies

Arduino

Visible light emitting diode with clear (non-diffused) package

Any silicon photodiode - e.g. BPW34 or TEFD4300

Miscellaneous resistors and capacitors

Optional oscilloscope to view waveforms

Background

Let’s say you want to set up a simple light beam detector. This might be part of a burglar alarm or a trigger for your bird-table camera. The source is a small LED, perhaps battery powered, the detector a photodiode plus amplifier. With a constant LED output, configuring a threshold light level to trigger the camera will be very difficult. The detected signal is likely very weak. Sunlight will probably dominate it. Passing clouds will give fast changes in light level and amplifiers will drift with temperature variations. It might even have a lot of 50/60 Hz pickup from mains wiring. DC is not a good approach – much better to amplitude modulate the light source and look for an AC signal.

How can we best measure this modulation, probably of low amplitude and buried in interference and noise?

Lock-in to the Rescue

signalMultiplication.png

On the internet you will find many articles on the theory of the lock-in amplifier. The idea is to multiply the noisy input signal moment-by-moment with a sinewave at the known frequency of the source modulation fmod. The sinewave, or reference wave, must be aligned in phase with the input modulation. In an analog world multiplication can be performed using a four-quadrant multiplier like the AD534/AD734 chips from Analog Devices.

An easier approach, as shown in the figure, is to multiply by a phase-aligned square wave. Multiplication by ±1 just requires an inversion and a switch, easily arranged with an op-amp and single transistor or a pair of opamps and an analog switch. The signal, AC-coupled to give zero DC value, on multiplication achieves a finite average value (the red line). Performance with the square wave is not quite as good as with a sinewave, but the greater convenience often wins out. Such switched gain circuitry is available in the superb AD630 “balanced modulator/demodulator” chip, whose excellent gain-match and wide bandwidth allow the extraction of signals buried deep in noise. The AD630 has been a favourite at least since the ‘80s. However, it is not cheap as chips!

Lock-in Instruments

lockinInstrument.png

A real analog lock-in instrument looks a bit like this. It has a signal input with lots of adjustable gain, a reference input, a multiplier, low pass filter and a DC voltmeter/display. An oscillator, internal or external, serves both to modulate the source light and to supply the reference input to the multiplier. Hence we need a cable connecting the LED source assembly to the lock-in.

Why is this whole contraption called a lock-in? The only real LOCK-IN part of it is behind the reference input, where an internal clean, stable oscillator “locks in” in frequency and phase to the perhaps far-from-sine reference input. Alternatively you can call the system a “synchronous detector” or “phase-sensitive detector” or “tracking AC voltmeter”. Whatever you choose, it’s an AC voltmeter combined with a frequency-domain filter centred on the frequency of the reference oscillator. The lock-in usually also has adjustments to shift the phase of the reference signal to align perfectly with the possibly delayed or phase shifted noisy signal, in order to maximise the measured value. This is usually necessary when the source modulation is performed by a rotating chopper disc or other mechanical means.

Lock-in As Filter

filterLP.png

What about the low-pass filter LP? As can be seen by doing the maths of the multiplication, the lock-in acts like a filter centred on the modulation frequency fmod with a width (in Hz) determined by the filter time constant RC. For instance, if R = 100 kohm and C = 10 µF, 1/RC is 1 Hz. So we have built a 2 Hz wide filter centred on the modulation frequency. Making such a filter in conventional analog circuitry would be tricky. Even more impressive is the fact that this 2 Hz wide filter automatically tracks the reference, even if it slowly drifts (it’s “locked in” to the known LED drive frequency. The RC-filter low-pass response has been shifted up to the reference frequency.

Example of Analog Synchronous Detection

Demod_DG419.png

As mentioned above, there are many ways to implement analog multiplication, especially in ±1 form. Here is one method that is easy to understand. The input signal is passed to a gain = 1 follower and a gain = -1 inverter, both made with opamps. Then an analog switch alternately selects the two signals, before passing them to an integrator. Even a simple RC low-pass filter will work; it acts as an integrator as long as fmod>>1/RC. A true integrator can be built with an opamp, although the low frequency gain must be limited with the large resistor across C.

Into the Digital World

digitalSync2.png

Let’s now turn to a digital implementation. We need one digital output to switch the LED and an analog to digital converter (ADC) to sample the noisy signal. The microprocessor-based lock-in then looks like this, a simple loop with two measurements:

{

Switch on the light source

Make an analog measurement with the ADC: Von

Switch off the light source

Make an analog measurement with the ADC: Voff

Form the difference Vdiff = Von - Voff

Average the difference values

} // go round again.

Occasionally display or transmit the result.

You can perform the average by adding N measurements and then dividing by N. An alternative is the exponential moving average, which at each step adds a small fraction of the new measurement to the previous average:

NewAvg = p * PrevAvg + (1 – p) * Vdiff where p is a floating point number between 0 and 1. If p is almost 1 then the averaging extends over many samples. The output value will change only slowly with time. If p is close to 0 the output value will quickly track changes in input, but suppression of noise will be inferior.

To avoid using slow floating-point calculations in a microcontroller without floating point hardware support we can write instead:

NewAvg = (15 * PrevAvg + 1 * Vdiff) / 16 or

NewAvg = (63 * PrevAvg + 1 * Vdiff) / 64 etc.

In this way the division is a fast right-shift operation. Just be careful with your integer sizes; 63 * PrevAvg can become pretty big, but it still has to fit in the integer type you choose.

So how do we do this in hardware? Yes, there are scorching-fast micros out there and DSP engines with fancy maths and averaging built-in, but you can do pretty well with an Arduino, even in a simple loop as outlined above. (Yes, even using the maligned delay() function!). It has a 10-bit analog to digital converter for sampling the input. The modulation frequency fmod will be quite low, but it will show the principles. With a bit more effort you can use a PWM output to drive the LED and timers and interrupts to perfectly align the measurement actions. An 8-bit PIC is another good choice; choose one that has a lot of support on the internet, like the PIC 16F877. Code development is straightforward in MPLAB and the xc8 compiler.

Minimalist Arduino Demonstrator

syncDetMinimalArduino2.png

A minimalist demo of the lock-in can be built with an Arduino and a few components. Here PORTB D12 drives the LED with a few mA. Analog input A0 is biassed near the center of its range with a pair of equal resistors. Hence the values measured with analogRead() will be around 512. Almost any photodiode or phototransistor can be used as detector. We had some BPW34 and TEFD4300 photodiodes, used here under reverse bias. The µA-level photocurrent ip generates a few mV AC at A0. Capacitive coupling goes some way to removing DC and low frequency interference. Sensitivity is primarily determined by the parallel combination of the 1Mohm resistors. The simple code below will demonstrate the principles. As shown, this generates a square wave modulation at around 438 Hz, nicely above the usual interference at 50/60 and 100/120 Hz.

/* Minimalist Synchronous Detector

minimalSyncDet.ino August 2025

OptikGeek for Instructables

438.43 Hz

*/

//*********************************************** GLOBAL DECLARATIONS

const int LED = 12; // Drive for source LED

float Vavg = 0.0; // Averaged sensor reading

float p = 0.95; // Exp. averaging parameter (p->1.0 slower)

long previousMillis = 0; // Stores last time measured

long resultInterval = 5000; // ms - Interval between results


//*********************************************** SETUP

void setup() {

pinMode(A0,INPUT ); // A0 is predefined in compiler

pinMode(LED,OUTPUT);

// D6(MSB) - D2(LSB) for R-2R DAC

DDRD = DDRD | B01111100; // Sets pins 2 to 6 as outputs

Serial.begin(115200);

}


//******************************************************** LOOP

void loop() {

int Von, Voff;

long currentMillis;

digitalWrite(LED,HIGH); // LED on

delay(1);

Von = analogRead(A0);

digitalWrite(LED,LOW); // LED off

delay(1);

Voff = analogRead(A0);

Vavg = Vavg * p + (1.0 - p)* (float)(Von - Voff); // Average


// DAC output - optional

int DACval; // Range is -512 - 511 (10 bits)

DACval = (512 + (int) Vavg)>>5; // Shift to range 0 - 1023 (10 bits),

// then divide by 32 (range 0 - 31)

DACval = DACval <<2; // Shift up to bits 2 - 6.

writeDAC(DACval);


currentMillis = millis();

// Send the result occasionally

if(currentMillis - previousMillis > resultInterval){

Serial.print("Rslt: ");

Serial.println(Vavg);

previousMillis = currentMillis;

}

}

void writeDAC(int DACval) // Safely write to PORTD

{

// Define the mask (bits you want to change: D2-D6)

uint8_t mask = 0b01111100;

PORTD = (PORTD & ~mask) | (DACval & mask);

}

The loop runs continuously. To see the measurement result we can print Vavg occasionally. Observing Vavg on the serial monitor is useful to see how much the returned values vary under dark conditions and under interference from fluorescent lights, PC-screens etc. When variable p is small, suppression of these interferences is low. Change p to see the change in noise-suppression.

If you have an oscilloscope you can view Vavg after every code loop by converting back into analog form. The R-2R DAC on pins D6-D2 does this, optional but highly didactic. Changing p from 0.01 to 0.99 and changing LED-photodiode coupling you will see the large difference in response time.

Conclusion

There is a lot more to the commercial lock-in amplifier or synchronous detector, with antialiasing filters, higher frequency sampling, simultaneous multiple-frequency measurements, fancier averaging and full Fourier analysis, but the simple idea of sampling with the source on and then off followed by averaging the differences can improve many types of measurement. Analog experiments can perform very well, although most new commercial lock-in amplifiers go for digital fanciness. Whichever you choose, the lock-in amplifier is a supremely useful technique for performing low-level measurements in optics and in many types of instrumentation science.

In another Instructable we will deal with the problem of widely separated source and detector, where it is not possible to have a cable between source and detector. For much more detail on practical optical measurement systems, including lock-in methods, see “Photodetection and Measurement”, Mark Johnson, ISBN-0-07-140944-0 McGraw-Hill 2003 and the references below.

Analog Devices AN-307 Description of the AD630:

https://www.analog.com/media/en/technical-documentation/application-notes/AN-307.pdf

Analog Devices AN-306 Synchronous system measures µOhm: