I have a project where I am in need of a amplifier with digitally adjustable gain.
There are many ways to construct a variable gain amplifier, one solution involves using a digital potentiometer in the negative feedback path around an op-amp.
A simplified schematic is shown below

Image sourced from Application note: ww1.microchip.com/.../01316A.pdf
The closed loop gain of the amplifier is now a function of the digiPOT’s wiper position:
Half of the wiper codes map to closed loop gains between 1 and 2. There isn’t a lot of choice for larger gains after a gain of 64 then next available choice is 128.
Pretty Neat! I don’t happen to need more than 20 kHz of bandwidth, so finding an op-amp with a gain-bandwidth product greater than 20kHz*128 = 2.6 MHz is not a problem.
Breadboard
It just so happens I have some digital potentiometers laying around.
Specifically, the Microchip MCP4131 digital POT, which has 7-bit resolution and a total ladder resistance of 10k.
I also have some Renesas ISL28291 dual-opamps.
Both have been sent to me by element14 (and the cool breadbroad, thanks element14!)
I tossed them onto a breadboard and used a RPI pico to interface with the MCP4131 (github.com/.../main)

Just like a rotary potentiometer the digiPOT has 3 terminals: A, B, W

Instead of a having a continuous resistance track and a movable wiper contact, the digi pot has 128 small resistors in a series string and an analog mux that can select any of the 129 tap points.
If you apply a fixed potential across the A and B terminals, then with the wiper to set to mid-scale code, the output voltage is half the input. At a wiper code of 0, ideally the wiper voltage should be 0 (unfortunately due to the resistance of the terminal disconnect switch it slightly greater than 0).
User beware, behavior at the extreme tap-points is worse than advertised.
At a wiper code of 127, I measured a gain of 80x instead of the ideal value of 128x. Disappointing.
There also isn’t a lot of ‘gain resolution’, the previous wiper code of 126 provides an ideal gain of 64x.
Compounding 2 for more gain and resolution
To achieve a higher total gain and have more gain steps to choose from, I put 2 in series.

Now with 2 stages, there are 5363 unique gain values.

The vast majority of the unique gains are below 50 dB. Above 50 dB there are 55 unique gain values.
Here is a scopeshot of the PGA cycling between a gain of 1 and 6

The brief excursion on the scope plot is python being slow, micropython takes its sweet time between the spi write of the first and second digiPOT.

In summary, I am pretty happy with the dynamic range of the amplifier. The amplifier can be programed to provide gains of anywhere between unity and 10000x with 20 kHz of bandwidth and an input referred noise of approximately 3nV/rootHz.
Not bad for parts I had laying around. All the big name semi’s have PGAs with lower noise and more bandwidth all integrated within a single IC for reasonable prices. So, if you need one, you can shop around for a pre-engineered solution.
