Software and Teensy Setup

A project log for ADA2200 Lock-In Amplifier

This project will attempt to explore and explain the use of the Analog Devices ADA2200 to build Lock-in Amplifiers.

doctekdoctek 07/07/2018 at 23:140 Comments

It just hit me that I have not uploaded or described the Arduino software that handles clocking, configuration, and sampling of the ADA2200. Sure, you could grab the program from the Spectrophotometer Project, but it’s got extra stuff in it that is really just confusing for this project. So the file Lockin_Control.ino in the files section is the program specific to this project. I am running Arduino 1.8.2; the Board is the Teensy 3.1/3.2. The Serial port is the USB link of Teensy, not a traditional serial (RS-232) link.

Software for the
ADA2200 must perform three tasks. First, the SPI port must be
manipulated to configure the ADA2200. Having an interface to change
the configuration on the fly is also useful. Most Arduino
configurations (including Teensy 3.1/3.2) have a SPI communication
package. If your are using more than one device, be sure to read the
info at on SPI. Several commands can be sent via the Arduino
Serial Monitor to change configuration.

Second, we use the
software to configure the master clock to the ADA2200 so no
additional crystal or oscillator is needed. The FrequencyTimer2
package can be used for this. Additional details at

Third, one channel of the analog-to-digital converter (ADC) is used to sample data from the ADA2200. Timing for the sampling is provided by the Synchronization signal from the part; Syn on our board. This signal is connected to an Arduino digital pin and generates an interrupt whenever it occurs. This interrupt starts the sampling by the ADC. The ADC will cause an interrupt each time a sample is ready. These samples can be saved and averaged. They can also be displayed on the Arduino Serial Monitor, or uploaded by another program running on a PC.

Here’s the connections from the Teensy 3.1/3.2 to the ADA2200 board or the breadboard:

GND to GND on the breadboard

D5 is CLK to the ADA2200 Board

D11 is MOSI for the SPI Bus, to MOSI on ADA2200

D10 is /CS for the SPI Bus, to CS on ADA2200

D14 is SCK for the SPI Bus, to Sck on ADA2200

D17 (really A3, analog input to the A/D), can be connected to either OPs or ONs as desired

D20 is the sample clock input from Syn of the ADA2200

USB5V goes to a 3.3V linear regulator to supply 3.3V to the breadboard

The MISO signal is shared with RCK, so RCK is the signal I choose. I used MISO briefly when I was trying to verify that the part was communicating but it is no longer useful. RCK is very useful!

Time to open Lockin_Control.ino! This is best done in the Arduino environment so you can upload the code to the Teensy.

Look at the
#includes to start things off. I’m using the SPI, FrequencyTimer2,
and ADC packages from for the Teensy3.1/3.2. These may
already be part of your Arduino environment, but check to be sure.

Next I declare some useful variables, pins, and modes; then instantiate an object or two. The SPI Settings are used below and the ADC is configured further and used below.

The Setup() function is pretty obvious. Objects are configured, the Serial port is opened, ADC sampling is started, an opening message is sent, and the master clock is started. The configuration of the ADC is from the Spectrophotometer Project; lots of experimentation could still be done. Since the sampling is pretty slow, the slow settings seem appropriate for now. The alternate SPI clock pin is selected to avoid the pin that is connected to the LED.

More global variables are declared before the Loop() function. These are used for data collection and averaging; explained below.

The Loop() function waits for commands over the Serial (USB) port. If a character is available, the switch statement processes it. (In looking at this code, I notice it is lacking a default case clause. It should probably have one in case of errant input, but it reminds me to emphasize an important point. This parser is written simply to help the user interact with the ADA2200. It assumes the user has good intentions. What might happen with malicious input is unclear. Of course, if real maliciousness is intended, then the Arduino code can be simply modified!)

Assuming valid inputs, the first case handles numerical input. Decimal digits are accepted and each subsequent one is added to the previous value multiplied by 10. The result is available for use in other cases, but is currently used only by the “g” command.

The “g” case sets the number of samples the ADC is to gather. Setting this value causes sample collection to begin. When the desired number of samples has been gathered, each one is sent out the Serial (USB) port; processing may also be done with the “a” command. Once the desired number is reached, no further samples are collected. The ADA2200 puts out 8 samples over one RCK cycle, so sampling should be modulo 8. This is not enforced by the software.

Cases “i” and “q” use the SPI port to configure the ADA2200 to process the In-Phase or Quadrature component of the incoming signal respectively. The serious experimenter should have a look at the commands being sent and at Tables 10 and 11 of the data sheet. There may be better ways to configure the ADA2200; I have found this one to work.

Case “r” uses the SPI part to do a software Reset of the ADA2200. I have found that this is necessary between “i” and “q” commands when I want to change between them. I have also found that the RESET button on the ADA2200 board does basically the same thing.

Case “a” is only interesting if samples have been gathered with the “g” command. Given a number of samples, they will be processed in 8 sample groups. The Average and the median are calculated.

That’s the end of the commands, but there is one other section in Loop() worth mentioning. If data has been sampled and the requested number of samples has been collected, the sample values will be sent out the Serial port.

The final functions are the Interrupt Service Routines. The isrService() responds to the Syn synchronization signal falling edge on D20. When that interrupt occurs, the ADC is started. When a sample is complete, the ADC interrupts and adc0_isr() runs to save the sample if data gathering is enabled. There is no need to start or stop the interrupts as no data is saved unless it is requested. Interrupt processing is quick enough that this is no problem.

Command examples:

The Arduino Serial Monitor is used with “Both NL & CR” selected for line endings. Type a <CR> to send each command to the Teensy.

To Reset the ADA2200 and configure it for In-Phase operation:



To Gather 8 samples and Average them:



OK! That’s the software!