¿ªÔÆÌåÓý

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


John
 

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)
?
?
?
#define OPTION_SMETER
#define OPTION_SOFTWAREAGC
?
//Called from the loop() function
void doSoftwareAGC() {
#ifdef OPTION_SMETER
?
? 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;
? ? ? break;
? ? }
? }
#ifdef OPTION_SOFTWAREAGC
? //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) {
? ? setFrequency(frequency);
? ? //Adjust meter by IF attenuation except for the first 1000Hz. Approx 6dB per 500Hz.
? ? scaledSMeter += (firstIfShift > 10000 ? (firstIfShift - 10000) / 5000 : 0);
? }
#endif? //OPTION_SOFTWAREAGC
#endif? //OPTION_SMETER
?
}
?


 

John

I applaud your ideas and wonderful experiments.
When I first implemented IF-Shift, I saw that the skirt characteristic of the 45Mhz filter was wide (not narrow).
So I used a 12Mhz crystal section to reduce the ambient noise.

I thought of three things through Shift of IF1 (45Mhz).
? -?Receiver improvements
? ??I felt a slight improvement in the sound when I shifted the IF1 from 3000 to 7000 Hz.
? ??I thought that the center frequency of IF1 was optimized for my radio.
? ? (Now the center frequency of IF1 is fixed)

? - IF-Shift2
? ? So I tried to add a feature that allows users to control the receive frequency to improve or reduce the reception rate by shifting the pass frequency of 45Mhz.

? -?If I find an IF shift value that I can use as a filter, I want to use it as a CW Filter.
? ??I was trying to imitate the CW filter by cutting one side from IF1 (45Mhz) and cutting the other side from IF2 (12Mhz).
? ? I have been experimenting with this part lately, but I have not yet achieved satisfactory results.
? ? For this part, I almost did not have an idea, so I almost got to give up.

I never thought about using this part as an AGC.?
Later, when I add the S.Meter to get the Signal Strength when I work on the firmware, I want to apply your code.

Thank you for sharing this great idea and code.

2018-04-01 7:50 GMT+09:00 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)
?
?
?
#define OPTION_SMETER
#define OPTION_SOFTWAREAGC
?
//Called from the loop() function
void doSoftwareAGC() {
#ifdef OPTION_SMETER
?
? 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;
? ? ? break;
? ? }
? }
#ifdef OPTION_SOFTWAREAGC
? //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) {
? ? setFrequency(frequency);
? ? //Adjust meter by IF attenuation except for the first 1000Hz. Approx 6dB per 500Hz.
? ? scaledSMeter += (firstIfShift > 10000 ? (firstIfShift - 10000) / 5000 : 0);
? }
#endif? //OPTION_SOFTWAREAGC
#endif? //OPTION_SMETER
?
}
?



--
Best 73
KD8CEC / Ph.D ian lee
kd8cec@...
(my blog)


John
 

Hello Ian,

First let me thank you for putting such a great software for the others to use and modify.

Me too I noticed that the two filters are not quite aligned as defined by the factory setting, but I had other more urgent things to investigate. Maybe that could be another setup, although the extra gain is not that significant for the added complexity.

I haven't looked at the CW filter side, but I think the IF1 filter is too wide to make any noticeable change.

Maybe you can help me sort out one thing that bothers me in my IF1 filter curve.

Farhan stated that this filter should be around 15kHz wide. I presume that is it's -6dB bandwidth.

My graph indicates a -6dB bandwidth of around 2Khz, which is way too small.

Also if my graph is right, using the skirt should produce attenuation of the low or high side of the audio by around 10dB which should be audible.?But in practice it is not audible.

So I strongly suspect that I have the horizontal scale wrong by a factor of 10, and it should be 20kHz per marker instead of 2kHz.

But I triple checked my code and I can't find the error. So here are the other key parts of the code:

A] in the menu, tuning the IF1 shift:

? ? if (knob > 0)
? ? ? firstIfShift -= 1001;
? ? else if (knob < 0)
? ? ?firstIfShift += 1001;
?
and B] in my setFrequency function for the USB case as an example I do:

? ? ? si5351bx_setfreq(2, SECOND_OSC_USB? + firstIfShift - usbCarrier + f? - ((isIFShift && !inTx) ? ifShiftValue : 0));
? ? ? si5351bx_setfreq(1, SECOND_OSC_USB + firstIfShift);
?
To my understanding this should produce steps of 100Hz.

Where is my logic wrong?

All the best,

73, John (VK2ETA)


 

The crystal filters are not quite aligned when using the standard firmware
as per this post:??/g/BITX20/message/44278
A somewhat related post is this:??/g/BITX20/message/44515

Curious that John in post 45675 was not noticing a change in audio quality, just signal strength.

Jerry


On Sat, Mar 31, 2018 at 06:33 pm, John wrote:
Me too I noticed that the two filters are not quite aligned as defined by the factory setting,


John
 

Hello Jerry,

Thanks for the reply.?

Yes I am asking myself the same question (see my previous post looking for a logic gap).

I haven't been able to find an amateur station strong enough to fully test it and I have had to rely on AM broadcast stations for my tests.

I would be great if someone could load the modified software (in the file section) and do a real-life comparison by manually shifting the 1st IF in the presence of S9+20 and over stations.

All the best,

73, John (VK2ETA)


John
 

Puzzle solved by Ian Lee. Thank you Ian.

The issue was that in the fonts in my computer, lowercase "L" and number "1" appear exactly the same. So 1000l (l for Long) reads as 10001.

So my frequency numbers are all too small by a factor of 10.

Here is the corrected graph and it explains why the slope of the filter is not noticeable on the audio since we are introducing about 1dB of impact between 500Hz and 2400Hz when using the slope of the filter.



Now the theory matches the practice..hihi

It also means that the first IF filter is (in my case) around 7000Hz out of alignment with my 2nd IF filter, as mentioned before.

Please note that Ian has released a video of the 1st If shift. See??
I will correct and re-upload the test sketch as well.

All the best,

73, John (VK2ETA)


 

Adding L's to 32 bit constants seems to be a thing with this group.
I doubt it's necessary, even on our Nano under the Arduino IDE where an int is 16 bits.
C compilers can easily determine that they must treat 12345678 as a 32 bit integer, and do so.
They have done so for the last 40 years.
See section "A2.5.1 Integer Constants" in Appendix A (The Reference Manual), in the second edition of K&R C.

My copy of K&R has nothing to say about 64 bit long-longs, however.?
They weren't a thing in 1988.

Jerry, KE7ER



On Sat, Mar 31, 2018 at 10:17 pm, John wrote:
The issue was that in the fonts in my computer, lowercase "L" and number "1" appear exactly the same. So 1000l (l for Long) reads as 10001.


John
 

I just wished they were written as capital L. It would have saved me some head scratching...hihi

73, John


John
 

Corrected code snippets for programmers:


#define OPTION_SMETER
#define OPTION_SOFTWAREAGC


void doSoftwareAGC() {
#ifdef OPTION_SMETER
?
? int newSMeter;
?
? //VK2ETA S-Meter from MAX9814 TC pin
? newSMeter = analogRead(ANALOG_SMETER);
? //Serial.print("newSMeter:"); Serial.println(newSMeter);
?
? //Faster attack, Slower release
? currentSMeter = (newSMeter > currentSMeter ? ((currentSMeter * 3 + newSMeter * 7) + 5) / 10 : ((currentSMeter * 7 + newSMeter * 3) + 5) / 10);
?
? //Serial.print("currentSMeter:"); Serial.println(currentSMeter);
? //Scale it
? scaledSMeter = 0;
? for (byte s = 8; s >= 1; s--) {
? ? if (currentSMeter > sMeterLevels[s]) {
? ? ? scaledSMeter = s;
? ? ? break;
? ? }
? }
? //Serial.print("scaledSMeter, un-adjusted:"); Serial.println(scaledSMeter);
#ifdef OPTION_SOFTWAREAGC
? //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.
? ? // 10kHz or 5kHz per step.
? ? 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) {
? ? setFrequency(frequency);
? ? //Serial.print("firstIfShift:"); Serial.println(firstIfShift);
? ? //Adjust meter by IF attenuation except for the first 10Khz. Approx 6dB per 5KHz.
? ? scaledSMeter += (firstIfShift > 10000 ? (firstIfShift - 10000) / 5000 : 0);
? ? //Serial.print("scaledSMeter, adjusted:"); Serial.println(scaledSMeter);
? }
#endif? //OPTION_SOFTWAREAGC
#endif? //OPTION_SMETER
?
}



//And the setfrequency function becomes:

?
void setFrequency(unsigned long f) {
? f = (f / arTuneStep[tuneStepIndex - 1]) * arTuneStep[tuneStepIndex - 1];
?
? setTXFilters(f);
?
? if (cwMode == 0)
? {
? ? if (isUSB) {
? ? ? //si5351bx_setfreq(2, SECOND_OSC_USB - usbCarrier + f? + (isIFShift ? ifShiftValue : 0));
? ? ? si5351bx_setfreq(2, SECOND_OSC_USB? + firstIfShift - usbCarrier + f? - ((isIFShift && !inTx) ? ifShiftValue : 0));
? ? ? si5351bx_setfreq(1, SECOND_OSC_USB + firstIfShift);
? ? }
? ? else {
? ? ? //si5351bx_setfreq(2, SECOND_OSC_LSB + usbCarrier + f + (isIFShift ? ifShiftValue : 0));
? ? ? si5351bx_setfreq(2, SECOND_OSC_LSB? + firstIfShift + usbCarrier + f + ((isIFShift && !inTx) ? ifShiftValue : 0));
? ? ? si5351bx_setfreq(1, SECOND_OSC_LSB + firstIfShift);
? ? }
? ? //VK2ETA Bring back the BFO to default if using IF Shift and we are TXing
? ? si5351bx_setfreq(0, usbCarrier + ((isIFShift && !inTx) ? ifShiftValue : 0));
? }
?
? else
? {
? ? if (cwMode == 1) { //CWL
? ? ? //si5351bx_setfreq(2, SECOND_OSC_LSB + cwmCarrier + f + (isIFShift ? ifShiftValue : 0));
? ? ? si5351bx_setfreq(2, SECOND_OSC_LSB? + firstIfShift + cwmCarrier + f + ((isIFShift && !inTx) ? ifShiftValue : 0));
? ? ? si5351bx_setfreq(1, SECOND_OSC_LSB + firstIfShift);
? ? }
? ? else {? ? ? ? ? ? //CWU
? ? ? //si5351bx_setfreq(2, SECOND_OSC_USB - cwmCarrier + f + (isIFShift ? ifShiftValue : 0));
? ? ? si5351bx_setfreq(2, SECOND_OSC_USB? + firstIfShift - cwmCarrier + f - ((isIFShift && !inTx) ? ifShiftValue : 0));
? ? ? si5351bx_setfreq(1, SECOND_OSC_USB + firstIfShift);
?
? ? }
? ? //VK2ETA Bring back the BFO to default if using IF Shift and we are TXing
? ? si5351bx_setfreq(0, cwmCarrier + ((isIFShift && !inTx) ? ifShiftValue : 0));
?
? }
?





Jack Purdum
 

Amen...I've been saying this for years...

Jack, W8TEE


On Sunday, April 1, 2018, 2:10:47 AM EDT, John <passionfruit88@...> wrote:


I just wished they were written as capital L. It would have saved me some head scratching...hihi

73, John


 

¿ªÔÆÌåÓý

Any plans Ian to add local oscillator setup values to ¦ÌBITX Manager, so that we can align the two IFs.
Measured mine and found 56,994986 USB / 32,994993 LSB.

73 Nikos
SV1IYF

?On 1/4/2018 8:17 ¦Ð¦Ì, John wrote:

......
It also means that the first IF filter is (in my case) around 7000Hz out of alignment with my 2nd IF filter, as mentioned before.
......






 

I just wanted to add that I have a special spot for what I consider the proper use of trinary's like what you have done.

Nothing more to add, keep on keeping on!

73 Rob AG5OV


 

Might be possible to use John's 45mhz IF filter trick to attenuate CW also.

Currently, CW-KEY unbalances the first mixer at T2 pins 3,5 when sending CW.
We could have CW-KEY instead unbalance the second mixer, at T4 pins 3,5.


John
 

Thank you Rob, but luck sometimes has it's place too.

It happened that I noticed that effect when chasing my multiple birdies before replacing the Arduino Nano, and I mentioned a mis-alignment then and its effect on gain, thought about it, then left that idea aside until recently...hihi

73, John?


John
 

Hello Jerry,

Interesting point. How would you generate the Tx frequency?

Clock 1 would need to be in the vicinity of 45Mhz +/- for the attenuation. The image generated in the clock 2 mixer would be again well over the LPF, so no issue there.

Then I am not sure what the gain of Q20-22 stage would do to the driving signal level. Maybe with sufficient shift in clock 1 to attenuate the signal, re-amplify in that Q20-22 stage and it could be of the right level?

73, John


 

Could drive R104 where CW-KEY comes in with the wiper of a 10k pot,
the ends of that 10k pot go to CW-KEY and ground,
So when not keyed, pins 3,4 of the transformer are at ground.
When keyed, pins 3,4 maybe rise up to a quarter volt DC or so.
Adjust the pot for an appropriate power level when operating CW.

Though if you did over-drive the final with too big of a signal due to amplification
at Q20,21,22,? may not be the end of the world since for CW we don't care if the final is linear.

If you drove CW-KEY with a mike amp instead of a key, would have a modulator
somewhat like what's going on at T7.

The 0.1uF cap at C1 is a quick attempt at key shaping, once the pot gets adjusted for proper drive level?
then perhaps choose C1 for rise and fall times of the keying envelope of 5ms or less to avoid key clicks,
not terribly critical on a 10W rig.

Jerry, KE7ER



On Mon, Apr 2, 2018 at 03:05 pm, John wrote:

Then I am not sure what the gain of Q20-22 stage would do to the driving signal level. Maybe with sufficient shift in clock 1 to attenuate the signal, re-amplify in that Q20-22 stage and it could be of the right level?