AGC for uBITx controlled by I2C via Software

Nick VK4PLN admits he has tried just two AGC approaches on BITx rigs: the VK3YE AGC (which is shall we say very illuminating) and the ADAFRUIT TPA2016 I2C module.

Nick found the VK3YE solution messed with the audio quality, made it all scratchy, and still didnt handle local 100w stations well …

Now after playing with the TPA for a few days he is very happy with the results.  Audio has good depth and AGC is responsive, and the unit also gives a nice increase in gain.

One trick for others who want to implement this,  is that you will need to add some code to the Adafruit library to implement the enableNoiseGate(false); function.    We need to turn the NoiseGate off or else the AGC will not ramp up with only background noise and you will not hear anything until a loud signal comes on.  [EDITOR notes that this could be used as a kind of SQUELCH function].

Also the speaker output is NOT grounded, you need to isolate your SPEAKER jack so that the – ve line from the TPA2016 is direct to the speaker with no chassis grounding…   Output from the amplifier can’t be fed into another amplifier.

The Best part in Nick’s opinion is that all of the AGC related settings are customisable if you want.  If not, just use the voice settings from the datasheet.   Nick says the defaults work great!

Stereo 2.8W Class D Audio Amplifier – I2C Control AGC – TPA2016

Nick says he will post the code to the list along with a few pics… This extra info should appear here shortly.

REFERENCE

And the board installed in Nick’s uBITx can be seen below.  It looks a real tidy build!

Software

Nik has now shared his software:

/*************************************************************************
VK4PLN’s AGC Code. Adafruit TPA2016
Add call to setupTPA2016(); to main code setup() in ubitx_20 after initOscillators();
**********/

#include <Wire.h>
#include “Adafruit_TPA2016.h”

Adafruit_TPA2016 audioamp = Adafruit_TPA2016();

void setupTPA2016() {

audioamp.begin();
// See Datasheet page 22 for value -> dBV conversion table
// Serial.println(“Right off, Left On,”);
audioamp.enableChannel(false, true);

// Noise Gate Threshold: Below this value, the AGC holds the gain to prevent breathing effects.
//Select the threshold of the noise gate (1,4,10,20mV) (0-3)
// Serial.println(“Noise Gate Threshold,”);
//Disable NoiseGate, we want to hear everything, even weak signals….
audioamp.enableNoiseGate(false);
audioamp.setNoiseGateThreshold(0);

// Fixed Gain: The normal gain of the device when the AGC is inactive.
// The fixed gain is also the initial gain when the device comes out of shutdown mode or when the AGC is disabled.
// value 6 seems to work ok… based on datasheet. Where gain is from -28 (dB) to 30 (dB)
// Serial.println(“Setting Fixed Gain”);
audioamp.setGain(-12); //-27 is ok? -12 is too high local stations arnt clipped…

// Compression Ratio: The relation between input and output voltage.
// AGC can be TPA2016_AGC_OFF (no AGC) or
// TPA2016_AGC_2 (1:2 compression)
// TPA2016_AGC_4 (1:4 compression) * Datasheet – Voice
// TPA2016_AGC_8 (1:8 compression)
// Serial.println(“Setting AGC Compression”);
audioamp.setAGCCompression(TPA2016_AGC_8);

// Limiter Level: The value that sets the maximum allowed output amplitude.
// Serial.println(“Setting Limit Level”);
audioamp.setLimitLevelOn();
// or turn off with
//audioamp.setLimitLevelOff();
audioamp.setLimitLevel(30); // range from 0 (-6.5dBv) to 31 (9dBV) (8.5dBv(30) as per datasheet)

//Maximum Gain: The gain at the lower end of the compression region
// Serial.println(“Setting AGC Max Gain (18-30db – (0-12)”);
audioamp.setAGCMaxGain(12);

/*
* For voice systems the attack time should be in the 2-ms region, with a hang time of about 0.3 sec,
* followed by a gradual recovery time of up to 1 sec.
* http://www.qsl.net/va3iul/Files/Automatic_Gain_Control.pdf
*
*/

// See Datasheet page 23 for value -> ms conversion table
// Serial.println(“Setting AGC Attack (0.1-6.7ms – (0-63))”);
audioamp.setAttackControl(3);

// See Datasheet page 24 for value -> ms conversion table
// Serial.println(“Setting AGC Hold (0.0137-0.8631ms – (1-63))”);
audioamp.setHoldControl(0);

// See Datasheet page 24 for value -> ms conversion table
// Serial.println(“Setting AGC Release (0.0137-0.8631ms – (0-63))”);
audioamp.setReleaseControl(4);

}

Also, need to add this new function to Adafuit library after the existing enableChannel function:

// Turn on/off Noise Gate
void Adafruit_TPA2016::enableNoiseGate(boolean ng) {

uint8_t setup = read8(TPA2016_SETUP);
if (ng)
setup |= TPA2016_SETUP_NOISEGATE;
else
setup &= ~TPA2016_SETUP_NOISEGATE;

write8(TPA2016_SETUP, setup);
}

And the line for the header file:

void enableNoiseGate(boolean ng);

in .h file:
void setNoiseGateThreshold(uint8_t thresh);

in .cpp file

void Adafruit_TPA2016::setNoiseGateThreshold(uint8_t thresh){ //Added by VK4PLN
if (thresh > 3) return; // max threshold is 3 (20mV)
uint8_t agc = read8(TPA2016_AGCLIMIT);
  agc &= ~(0x20);  // mask off bottom 5 bits
  agc |= thresh;        // set the limit level.
  write8(TPA2016_AGCLIMIT, agc);
}
Reference

BITx AGC kit

David N8DAH has assembled AGC kits for BITx transceivers.  These were designed for the BITx20 and BITx40, but should work fine in the uBITx.

The AGC design was posted on DuWayne KV4QB’s site found here and used with permission. All kits will come with:

  • PCB x 1
  • Parts placement layout x 1
  • 2N3904 x 1
  • 2N7000 x 1
  • 47uf x 2
  • 1N4148 x 1
  • 100R x 3
  • 100k x 3
  • 10k x 1 this is extra for the user to play with attack or input values.
  • 2k2 x 1
  • .1uf x 2 unmarked tan

Missing parts will be replaced.   

This is the 3rd run of the boards.  Many group members have this AGC already in use.

Cost and options:

#1 – Kits 13$ shipped

#2 – Pre-built OT service 15$ shipped and tested

Write to David if you want to reserve a kit.

Reference

NB these are sold out as of 29 January 2018.