The red trace shows the off tune signal attenuation produced by a single tuned circuit with a 'Q' of 1000. It is extremely sharp and is therefore suitable for receiving narrow band transmissions such as morse code.
The green trace shows the off tune attenuation produced by passing the signal through two tuned circuits in succession both of which have a 'Q' of 300.
The blue trace shows the effect of passing the signal through 4 tuned circuits in succession each of which has a 'Q' of only 100. This has a much broader peak making it suitable for speech and even music. It also provides much greater attenuation as you move away from the resonant frequency.
The source code for the above applet is shown below. Please bear in mind that this was the very first applet I ever wrote in Java!
/** Receiver Pass Band Display applet */
import java.awt.*;
public class passband extends java.applet.Applet
{
Font titleFont;
Color colour;
Color bgColour;
int X, Y; //dimensions of display window (in pixels)
int x; //horizontal pixel number -120 to +120
int y; //vertical pixel number 0 to -200
int xbias = 150; //x co-ordinate of tuned frequency of circuit
int ybias = 15; //y co-ordinate of zero attenuation line
Image buffer; //reference for an off-screen image buffer
Graphics gc; //graphics context for the off-screen image
public void init() {
Dimension d = size(); //get size of window as given in HTML applet tag
X = d.width; Y = d.height; //establish window width and height
buffer = createImage(X, Y); //create the off-screen image buffer
titleFont = new java.awt.Font("Courier", Font.PLAIN, 12);
int bgc = (0x00C0C0C0); //transparent light grey background
bgColour = new Color(bgc); //but transparency does not seem to work!
gc = buffer.getGraphics(); //graphics context reference for the off-screen image
gc.setColor(bgColour); //set background colour for the off-screen image
for(int i = 0; i < Y ; i++)
gc.drawLine(0, i, X - 1, i);
int oldx1 = 0;
int oldy1 = 0;
int oldx2 = 0;
int oldy2 = 0;
int oldx3 = 0;
int oldy3 = 0;
int sbias = 8; //bias to make kHz numbering line up
String s = "";
double L = .0000003422; //Inductance in Henries
double C = .0000003422; //Capacitance in Farads
double R1 = .001; //Resistance in Ohms to give a Q of 1000
double R2 = .003; //to give a Q of 333
double R3 = .01; //to give a Q of 100
double R1S = R1 * R1; //Square of Q = 300 resistance
double R2S = R2 * R2; //Square of Q = 100 resistance
double R3S = R3 * R3; //Square of Q = 30 resistance
gc.setColor(Color.darkGray); //colour for graticule
for (x = -120 ; x < 121 ; x += 10) { //plot every 10 pixels across
gc.drawLine(x + xbias, ybias, x + xbias, ybias + 200);
if (x == -100) {s = "-10"; sbias = 10;} //put the numbers
else if (x == -50) {s = "-5"; sbias = 6;} //in on the horiz
else if (x == 0) {s = "0"; sbias = 2;} //scale evey 5kHz
else if (x == 50) {s = "5"; sbias = 3;} //from -10 to +10
else if (x == 100) {s = "10"; sbias = 6;}
else sbias = 0;
if (sbias > 0) //if this line is a multiple of 5kHz, number it
gc.drawString(s, x + xbias - sbias, ybias + 212);
}
for (y = 0 ; y < 101 ; y += 10) { //every 20 pixels going downwards
gc.drawLine(xbias - 119, y + y + ybias, //draw a horizontal graticule line
xbias + 119, y + y + ybias);
if (y > 0 && y < 100) //number every line
gc.drawString("-" + y, xbias - 140, //except the top and bottom ones
y + y + ybias + 4);
}
gc.drawString("kHz", xbias - 8, ybias + 224); //put in the kHz label
gc.drawString("dBe", xbias - 142, ybias + 3); //put in the dBe label
// COMPUTE THE REACTANCE AT FREQ CORRESPONDING TO EACH X-PIXEL POSITION
for (x = -120; x < 121; x++) {
double w //COMPUTE THE CURRENT ANGULAR FREQUENCY
= x //No. of pixels from resonant frequency centre
* 628.31853 //times 100 x 2pi to convert to radians/second
+ 2921681.164; //absolute centre frequency 465kHz in radians/sec
double X //COMPUTE REACTANCE OF CIRCUIT AT THIS FREQUENCY
= w * L //inductive reactance
- (1 / (w * C)); //capacitative reactance
X = X * X; //Square of total reactance
// COMPUTE AND PLOT ATTENUATION FOR A SINGLE TUNED CIRCUIT OF Q = 1000
y = atten(R1, R1S, X, 1); //compute y pixel co-ordinate
PlotLine(Color.red, oldx1, oldy1);
oldx1 = x; //set up this time's new co-ordinates
oldy1 = y; //to be next time's old co-ordinates.
// ... AND FOR A PAIR OF TUNED CIRCUITS IN CASCADE EACH OF Q = 300
y = atten(R2, R2S, X, 2); //compute y pixel co-ordinate
PlotLine(Color.green, oldx2, oldy2);
oldx2 = x; //set up this time's new co-ordinates
oldy2 = y; //to be next time's old co-ordinates.
// ... AND FOUR TUNED CIRCUITS IN CASCADE EACH OF Q = 100
y = atten(R3, R3S, X, 4); //compute y pixel co-ordinate
PlotLine(Color.blue, oldx3, oldy3);
oldx3 = x; //set up this time's new co-ordinates
oldy3 = y; //to be next time's old co-ordinates.
}
}
int atten(double R, double RR, double X, int n) { //compute signal attenuation
double z = Math.sqrt(RR + X) / R; //the circuit's impedance
double Z = 1; //compounded impedance
for (int i = 0 ; i < n ; i++) { //for each circuit in cascade
Z = Z * z; //raise impedance to power =
} //No. of cascaded circuits
return( (int)(40 * Math.log(Z)) ); //give as natural log decibels
} //double because of y-scale
void PlotLine(Color colour, int oldx, int oldy)
{
if (x > -120 && y < 200) //if beyond first time through
{ //and y not overshot graticule
gc.setColor(colour); //set required colour for this trace
gc.drawLine( //draw a line from
xbias + oldx, ybias + oldy, //the previous point
xbias + x, ybias + y //to the new point
);
}
}
public void paint(Graphics g) { //(re)draw the screen image
g.drawImage(buffer, 0, 0, null); //from the off-screen image buffer
}
/* Robert J Morton, the author of this program,
is a poor but Right Honourable Fellow of the
Ancient and Noble Order of the Long-term Unemployed.
Offers of work please to: robmorton@clara.net */
}