#ubitx Progressive 50dB+ Software based RX (and TX) IF attenuation. #ubitx

John <passionfruit88@...>

This came about in the search for a greater range for my MAX9814 AGC circuit.
Stations, above S9+10 would produce distortion in the audio circuit. I isolated this to the MAX circuit as the distorsion would disappear if it was bypassed.
I was curious as to what the 1st 45Mhz filter shape was like and if there was some plateau to be used somewhere for attenuating the strong signals.
I modified Farhan's original software to include an "Adjust First If" menu item, in steps of 100Hz.
By using a local station's carrier aligned on 1,500Hz audio as a reference and an Android audio spectrum display I have plotted the response of the first crystal filter. This also gave me an idea of the effect on the audio of shifting the filter up and down. The "noise" in the graph below near the peak is the effect of changing from a measure every 1000Hz to a measure every 100Hz, plus the inaccuracy of my rudimentary instrumentation.

As you can see there are rather slow slopes on each side of the peak (which by the way is a little off-center by 700Hz approximately when compared to 1,500Hz).
I was concerned that when the filter center was shifted by several hundred or some thousands of hertz the slopes would introduce a strong biasing towards high or low audio frequencies. But I was surprised that it was not noticeable, or at least my ears can't detect it.
So I proceeded with changing Ian's software (1.04 based changes) to incorporate an automatic AGC step-down when the signal reaches S9+10 and and automatic step-up when it reached S0. In the middle range, the MAX audio circuit does the AGC job.
I used the up side of the filter as I would get some birdies on some of the shifts on the down side.
Now the uBitx can handle S9++++ stations with ease, that is until the first amplifier stage before the filter saturates which I suspect is unlikely in "normal" conditions.
The only concern would be for another, possibly even stronger, station which would be placed at the peak of the filter several KHz away and could produce intermod distortion. But I think the chances of that happening are pretty remote too.
So, it works quite well and is surprisingly effective.
It also works in reverse, with the transmit SSB signal being attenuated by the same amount, thereby leading to a possible ALC software control for the units which measure the power out (or maybe just the current), or use simply a set attenuation like for digital modes for example. Again, check the effect of the slope on the voice tone.
I have attached snippets of my code and have uploaded the modified uBitx software for testing the filter both in RX and TX in the  "Software based IF attenuation" folder.
I will soon publish the complete set of Ian's modified software and of the Arduino ATU unit, but I though this could be of use in the mean time since I saw discussions on IF AGC in the group.
All the best,
73, John (VK2ETA)
//Called from the loop() function
void doSoftwareAGC() {
  int newSMeter;
  //VK2ETA S-Meter from MAX9814 TC pin
  newSMeter = analogRead(ANALOG_SMETER);
  //Faster attack, Slower release
  currentSMeter = (newSMeter > currentSMeter ? ((currentSMeter * 3 + newSMeter * 7) + 5) / 10 : ((currentSMeter * 7 + newSMeter * 3) + 5) / 10);
  //Scale it
  scaledSMeter = 0;
  for (byte s = 8; s >= 1; s--) {
    if (currentSMeter > sMeterLevels[s]) {
      scaledSMeter = s;
  //Apply auto-shift of first IF to increase the dynamic range of the Audio AGC circuit
  long previousShift = firstIfShift;
  if (scaledSMeter >= 7) {
    //Reduce gain by shifting the first and second If by the same value, thereby
    //  leaving the RX frequency the same but using the slope of the roofing
    //  filter to deliver progressive attenuation.
    // 1000 or 500Hz per step. Values are in 1/10th of a Hz.
    firstIfShift += (scaledSMeter > 7 ? 10000 : 5000);
  } else if (firstIfShift > 0 && scaledSMeter < 1) {
    //Re-increase the gain if we reduced it earlier
    firstIfShift -= 5000;
    firstIfShift = firstIfShift < 0 ? 0 : firstIfShift;
  if (firstIfShift != previousShift) {
    //Adjust meter by IF attenuation except for the first 1000Hz. Approx 6dB per 500Hz.
    scaledSMeter += (firstIfShift > 10000 ? (firstIfShift - 10000) / 5000 : 0);

Join BITX20@groups.io to automatically receive all group messages.