* quarterwave_filter.cpp - Quarter wavelength filter implementation
*
* copyright (C) 2015, 2024 Andres Martinez-Mera <andresmartinezmera@gmail.com>
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this package; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
* Boston, MA 02110-1301, USA.
*
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "quarterwave_filter.h"
#include <QString>
#include <QMessageBox>
double QuarterWave_Filter::bw = 0;
double QuarterWave_Filter::fc = 0;
double QuarterWave_Filter::d_lamdba4 = 0;
QuarterWave_Filter::QuarterWave_Filter()
{
}
QString *QuarterWave_Filter::createSchematic(tFilter *Filter, tSubstrate *Substrate, bool isMicrostrip)
{
if (Filter->Class < 2)
{
QMessageBox::warning(0, QObject::tr("Error"),
QObject::tr("Quarter wave filters do not allow low-pass nor high-pass masks\n"));
return NULL;
}
double Zres;
double W_line, W_res, er_eff_line, er_eff_res, L_line, L_res;
double Z0 = Filter->Impedance;
fc = Filter->Frequency + 0.5 * (Filter->Frequency2 - Filter->Frequency);
d_lamdba4 = 0.25 * LIGHTSPEED / fc;
QuarterWave_Filter::bw = (Filter->Frequency2 - Filter->Frequency) / (fc);
QString *s = new QString("<Qucs Schematic " PACKAGE_VERSION ">\n");
QString c_s = "<Components>\n";
QString w_s = "<Wires>\n";
int x = 60;
int x_space = 50;
c_s += QStringLiteral("<Pac P1 1 %1 330 18 -26 0 1 \"1\" 1 \"%2 Ohm\" 1 \"0 dBm\" 0 \"1 GHz\" 0>\n").arg(x).arg(Filter->Impedance);
c_s += QStringLiteral("<GND * 1 %1 360 0 0 0 0>\n").arg(x);
w_s += getWireString(60, 180, 60, 300);
w_s += getWireString(60, 180, 90, 180);
x += 60;
if (isMicrostrip)
TL_Filter::getMicrostrip(Z0, fc, Substrate, W_line, er_eff_line);
for (int i = 0; i < Filter->Order; i++)
{
if (Filter->Class == CLASS_BANDPASS)
Zres = (pi*Z0*bw)/(4*getNormValue(i, Filter));
else
Zres = (4*Z0)/(pi*bw*getNormValue(i, Filter));
if (isMicrostrip)
{
TL_Filter::getMicrostrip(Zres, fc, Substrate, W_res, er_eff_res);
L_line = d_lamdba4/sqrt(er_eff_line);
L_res = d_lamdba4/sqrt(er_eff_res);
c_s += getLineString(isMicrostrip, W_line, L_line, x, 180, 0);
c_s += getTeeString(x+ 60 + x_space, 180, W_line, W_line, W_res);
c_s += getLineString(isMicrostrip, W_res, L_res, x + 60 + x_space, 60, 1);
if (Filter->Class == CLASS_BANDSTOP){
c_s += getMS_Open(W_res, x + 60 + x_space, 0, 1);
}
w_s += getWireString(x+30, 180, x+30+x_space, 180);
w_s += getWireString(x+60 + x_space, 90, x+60 + x_space, 150);
w_s += getWireString(x+60 + x_space + 30, 180, x+60 + x_space + 30 + x_space, 180);
}
else
{
c_s += getLineString(isMicrostrip, Z0, d_lamdba4, x, 180, 0);
c_s += getLineString(isMicrostrip, Zres, d_lamdba4, x+60+x_space, 60, 3);
w_s += getWireString(x+30, 180, x+90+2*x_space, 180);
w_s += getWireString(x+60 + x_space, 90, x+60 + x_space, 180);
}
if (Filter->Class == CLASS_BANDPASS){
if (isMicrostrip){
c_s += getMS_Via(0.5, x+40 + x_space, 30, 2);
}
else{
c_s += QStringLiteral("<GND * 1 %1 30 0 0 1 0>\n").arg(x + 60 + x_space);
}
}
x += 120 + 2 * x_space;
}
if (isMicrostrip)
{
c_s += getLineString(isMicrostrip, W_line, d_lamdba4/sqrt(er_eff_line), x, 180);
}
else
{
c_s += getLineString(isMicrostrip, Filter->Impedance, d_lamdba4, x, 180);
}
x += 80;
c_s += QStringLiteral("<Pac P2 1 %1 330 18 -26 0 1 \"2\" 1 \"%2 Ohm\" 1 \"0 dBm\" 0 \"1 GHz\" 0>\n").arg(x).arg(Filter->Impedance);
c_s += QStringLiteral("<GND * 1 %1 360 0 0 0 0>\n").arg(x);
w_s += getWireString(x, 180, x, 300);
w_s += getWireString(x-50, 180, x, 180);
c_s += QStringLiteral("<.SP SP1 1 70 460 0 67 0 0 \"lin\" 1 \"%2Hz\" 1 \"%3Hz\" 1 \"300\" 1 \"no\" 0 \"1\" 0 \"2\" 0>\n").arg(num2str(0.1 * Filter->Frequency)).arg(num2str(10.0 * Filter->Frequency));
if (isMicrostrip)
c_s += QStringLiteral("<SUBST Sub1 1 300 500 -30 24 0 0 \"%1\" 1 \"%2m\" 1 \"%3m\" 1 \"%4\" 1 \"%5\" 1 \"%6\" 1>\n").arg(Substrate->er).arg(num2str(Substrate->height)).arg(num2str(Substrate->thickness)).arg(Substrate->tand).arg(Substrate->resistivity).arg(Substrate->roughness);
c_s += QStringLiteral("<Eqn Eqn1 1 450 560 -28 15 0 0 \"S21_dB=dB(S[2,1])\" 1 \"S11_dB=dB(S[1,1])\" 1 \"yes\" 0>\n");
*s += c_s + "</Components>\n";
*s += w_s + "</Wires>\n";
*s += "<Diagrams>\n";
*s += "</Diagrams>\n";
*s += "<Paintings>\n";
*s += QStringLiteral("<Text 420 460 12 #000000 0 \"Quarter wave bandpass filter \\n ");
switch (Filter->Type)
{
case TYPE_BESSEL: *s += QStringLiteral("Bessel"); break;
case TYPE_BUTTERWORTH: *s += QStringLiteral("Butterworth"); break;
case TYPE_CHEBYSHEV: *s += QStringLiteral("Chebyshev"); break;
}
*s += QStringLiteral(" %1Hz...%2Hz \\n ").arg(num2str(Filter->Frequency)).arg(num2str(Filter->Frequency2));
*s += QStringLiteral("Impedance matching %3 Ohm\">\n").arg(Filter->Impedance);
*s += "</Paintings>\n";
return s;
}