2011-08-05 19:53:42 +00:00
|
|
|
/*
|
|
|
|
* twistedpair.h - twisted pair class definition
|
|
|
|
*
|
|
|
|
* Copyright (C) 2011 Michael Margraf <michael.margraf@alumni.tu-berlin.de>
|
|
|
|
* Modifications 2011 for Kicad: Jean-Pierre Charras
|
|
|
|
*
|
|
|
|
* This program 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 of the License, or (at
|
|
|
|
* your option) any later version.
|
|
|
|
*
|
|
|
|
* This program 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.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2012-09-21 17:02:54 +00:00
|
|
|
#include <cmath>
|
2019-12-05 14:03:15 +00:00
|
|
|
#include <cstdio>
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <cstring>
|
2011-08-05 19:53:42 +00:00
|
|
|
|
2020-10-13 01:01:25 +00:00
|
|
|
#include "twistedpair.h"
|
|
|
|
#include "units.h"
|
2011-08-05 19:53:42 +00:00
|
|
|
|
|
|
|
TWISTEDPAIR::TWISTEDPAIR() : TRANSLINE()
|
|
|
|
{
|
2018-06-07 13:44:20 +00:00
|
|
|
m_Name = "TwistedPair";
|
2020-08-07 00:09:33 +00:00
|
|
|
Init();
|
2011-08-05 19:53:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-08-07 00:09:33 +00:00
|
|
|
/**
|
|
|
|
* \f$ \theta = \arctan\left( T \cdot \pi \cdot D_{out} \right) \f$
|
2020-10-13 01:01:25 +00:00
|
|
|
*
|
2020-08-07 00:09:33 +00:00
|
|
|
* Where :
|
2020-10-13 01:01:25 +00:00
|
|
|
* - \f$ \theta \f$ : pitch angle
|
2020-08-07 00:09:33 +00:00
|
|
|
* - \f$ T \f$ : Number of twists per unit length
|
|
|
|
* - \f$ D_{out} \f$ : Wire diameter with insulation
|
2020-10-13 01:01:25 +00:00
|
|
|
*
|
2020-08-07 00:09:33 +00:00
|
|
|
* \f$ e_{eff} = e_{env} \cdot \left( 0.25 + 0.0007 \cdot \theta^2 \right)\cdot\left(e_r-e_{env}\right) \f$
|
2020-10-13 01:01:25 +00:00
|
|
|
*
|
2020-08-07 00:09:33 +00:00
|
|
|
* Where :
|
|
|
|
* - \f$ e_{env} \f$ : relative dielectric constant of air ( or some other surronding material ),
|
|
|
|
* - \f$ e_r \f$ : relative dielectric constant of the film insulation,
|
2020-10-13 01:01:25 +00:00
|
|
|
* - \f$ e_{eff} \f$ : effective relative dielectric constant
|
|
|
|
*
|
2020-08-07 00:09:33 +00:00
|
|
|
* \f$ Z_0 = \frac{Z_\mathrm{VACCUM}}{\pi \cdot \sqrt{e_{eff}}}\cosh^{-1}\left(\frac{D_{out}}{D_{in}}\right) \f$
|
2020-10-13 01:01:25 +00:00
|
|
|
*
|
2020-08-07 00:09:33 +00:00
|
|
|
* - \f$ Z_0 \f$ : line impedance
|
|
|
|
* - \f$ Z_\mathrm{VACCUM} \f$ : vaccum impedance
|
|
|
|
* - \f$ D_{in} \f$ : Wire diameter without insulation
|
2020-10-13 01:01:25 +00:00
|
|
|
*
|
2020-08-07 00:09:33 +00:00
|
|
|
* Reference for above equations :
|
2020-10-13 01:01:25 +00:00
|
|
|
*
|
2020-08-07 00:09:33 +00:00
|
|
|
* [1] : P. Lefferson, ``Twisted Magnet Wire Transmission Line,''
|
|
|
|
* IEEE Transactions on Parts, Hybrids, and Packaging, vol. PHP-7, no. 4, pp. 148-154, Dec. 1971.
|
2020-10-13 01:01:25 +00:00
|
|
|
*
|
2020-08-07 00:09:33 +00:00
|
|
|
* The following URL can be used as reference : http://qucs.sourceforge.net/tech/node93.html
|
|
|
|
**/
|
|
|
|
void TWISTEDPAIR::calcAnalyze()
|
2011-08-05 19:53:42 +00:00
|
|
|
{
|
|
|
|
|
2020-08-07 00:09:33 +00:00
|
|
|
double tw = atan( m_parameters[TWISTEDPAIR_TWIST_PRM] * M_PI
|
|
|
|
* m_parameters[PHYS_DIAM_OUT_PRM] ); // pitch angle
|
|
|
|
m_parameters[EPSILON_EFF_PRM] =
|
|
|
|
m_parameters[TWISTEDPAIR_EPSILONR_ENV_PRM]
|
|
|
|
+ ( 0.25 + 0.0007 * tw * tw )
|
|
|
|
* ( m_parameters[EPSILONR_PRM] - m_parameters[TWISTEDPAIR_EPSILONR_ENV_PRM] );
|
|
|
|
|
|
|
|
m_parameters[Z0_PRM] =
|
|
|
|
ZF0 / M_PI / sqrt( m_parameters[EPSILON_EFF_PRM] )
|
|
|
|
* acosh( m_parameters[PHYS_DIAM_OUT_PRM] / m_parameters[PHYS_DIAM_IN_PRM] );
|
|
|
|
|
|
|
|
m_parameters[LOSS_CONDUCTOR_PRM] =
|
|
|
|
10.0 / log( 10.0 ) * m_parameters[PHYS_LEN_PRM] / m_parameters[SKIN_DEPTH_PRM]
|
|
|
|
/ m_parameters[SIGMA_PRM] / M_PI / m_parameters[Z0_PRM]
|
|
|
|
/ ( m_parameters[PHYS_DIAM_IN_PRM] - m_parameters[SKIN_DEPTH_PRM] );
|
|
|
|
|
|
|
|
m_parameters[LOSS_DIELECTRIC_PRM] = 20.0 / log( 10.0 ) * m_parameters[PHYS_LEN_PRM] * M_PI / C0
|
|
|
|
* m_parameters[FREQUENCY_PRM]
|
|
|
|
* sqrt( m_parameters[EPSILON_EFF_PRM] )
|
|
|
|
* m_parameters[TAND_PRM];
|
|
|
|
|
|
|
|
m_parameters[ANG_L_PRM] = 2.0 * M_PI * m_parameters[PHYS_LEN_PRM]
|
|
|
|
* sqrt( m_parameters[EPSILON_EFF_PRM] ) * m_parameters[FREQUENCY_PRM]
|
|
|
|
/ C0; // in radians
|
2011-08-05 19:53:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
|
|
void TWISTEDPAIR::show_results()
|
|
|
|
{
|
2020-08-07 00:09:33 +00:00
|
|
|
setResult( 0, m_parameters[EPSILON_EFF_PRM], "" );
|
|
|
|
setResult( 1, m_parameters[LOSS_CONDUCTOR_PRM], "dB" );
|
|
|
|
setResult( 2, m_parameters[LOSS_DIELECTRIC_PRM], "dB" );
|
|
|
|
setResult( 3, m_parameters[SKIN_DEPTH_PRM] / UNIT_MICRON, "µm" );
|
2011-08-05 19:53:42 +00:00
|
|
|
}
|
|
|
|
|
2020-08-07 00:09:33 +00:00
|
|
|
void TWISTEDPAIR::showAnalyze()
|
2011-08-05 19:53:42 +00:00
|
|
|
{
|
2020-08-07 00:09:33 +00:00
|
|
|
setProperty( Z0_PRM, m_parameters[Z0_PRM] );
|
|
|
|
setProperty( ANG_L_PRM, m_parameters[ANG_L_PRM] );
|
2011-08-05 19:53:42 +00:00
|
|
|
|
2020-08-07 00:09:33 +00:00
|
|
|
// Check for errors
|
|
|
|
if( !std::isfinite( m_parameters[Z0_PRM] ) || m_parameters[Z0_PRM] < 0 )
|
|
|
|
{
|
|
|
|
setErrorLevel( Z0_PRM, TRANSLINE_ERROR );
|
|
|
|
}
|
2011-08-05 19:53:42 +00:00
|
|
|
|
2020-08-07 00:09:33 +00:00
|
|
|
if( !std::isfinite( m_parameters[ANG_L_PRM] ) || m_parameters[ANG_L_PRM] < 0 )
|
|
|
|
{
|
|
|
|
setErrorLevel( ANG_L_PRM, TRANSLINE_ERROR );
|
|
|
|
}
|
2011-08-05 19:53:42 +00:00
|
|
|
|
2020-08-07 00:09:33 +00:00
|
|
|
// Find warnings to display - physical parameters
|
|
|
|
if( !std::isfinite( m_parameters[PHYS_DIAM_IN_PRM] ) || m_parameters[PHYS_DIAM_IN_PRM] <= 0.0 )
|
|
|
|
{
|
|
|
|
setErrorLevel( PHYS_DIAM_IN_PRM, TRANSLINE_WARNING );
|
|
|
|
}
|
2011-08-05 19:53:42 +00:00
|
|
|
|
2020-08-07 00:09:33 +00:00
|
|
|
if( !std::isfinite( m_parameters[PHYS_DIAM_OUT_PRM] )
|
|
|
|
|| m_parameters[PHYS_DIAM_OUT_PRM] <= 0.0 )
|
|
|
|
{
|
|
|
|
setErrorLevel( PHYS_DIAM_OUT_PRM, TRANSLINE_WARNING );
|
|
|
|
}
|
2011-08-05 19:53:42 +00:00
|
|
|
|
2020-08-07 00:09:33 +00:00
|
|
|
if( m_parameters[PHYS_DIAM_IN_PRM] > m_parameters[PHYS_DIAM_OUT_PRM] )
|
|
|
|
{
|
|
|
|
setErrorLevel( PHYS_DIAM_IN_PRM, TRANSLINE_WARNING );
|
|
|
|
setErrorLevel( PHYS_DIAM_OUT_PRM, TRANSLINE_WARNING );
|
|
|
|
}
|
2011-08-05 19:53:42 +00:00
|
|
|
|
2020-08-07 00:09:33 +00:00
|
|
|
if( !std::isfinite( m_parameters[PHYS_LEN_PRM] ) || m_parameters[PHYS_LEN_PRM] < 0.0 )
|
|
|
|
{
|
|
|
|
setErrorLevel( PHYS_LEN_PRM, TRANSLINE_WARNING );
|
|
|
|
}
|
|
|
|
}
|
2011-08-05 19:53:42 +00:00
|
|
|
|
2020-08-07 00:09:33 +00:00
|
|
|
void TWISTEDPAIR::showSynthesize()
|
|
|
|
{
|
|
|
|
if( isSelected( PHYS_DIAM_IN_PRM ) )
|
|
|
|
setProperty( PHYS_DIAM_IN_PRM, m_parameters[PHYS_DIAM_IN_PRM] );
|
|
|
|
else if( isSelected( PHYS_DIAM_OUT_PRM ) )
|
|
|
|
setProperty( PHYS_DIAM_OUT_PRM, m_parameters[PHYS_DIAM_OUT_PRM] );
|
|
|
|
setProperty( PHYS_LEN_PRM, m_parameters[PHYS_LEN_PRM] );
|
|
|
|
|
|
|
|
// Check for errors
|
|
|
|
if( !std::isfinite( m_parameters[PHYS_DIAM_IN_PRM] ) || m_parameters[PHYS_DIAM_IN_PRM] <= 0.0 )
|
2011-08-05 19:53:42 +00:00
|
|
|
{
|
|
|
|
if( isSelected( PHYS_DIAM_IN_PRM ) )
|
2020-08-07 00:09:33 +00:00
|
|
|
setErrorLevel( PHYS_DIAM_IN_PRM, TRANSLINE_ERROR );
|
2011-08-05 19:53:42 +00:00
|
|
|
else
|
2020-08-07 00:09:33 +00:00
|
|
|
setErrorLevel( PHYS_DIAM_IN_PRM, TRANSLINE_WARNING );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !std::isfinite( m_parameters[PHYS_DIAM_OUT_PRM] )
|
|
|
|
|| m_parameters[PHYS_DIAM_OUT_PRM] <= 0.0 )
|
|
|
|
{
|
|
|
|
if( isSelected( PHYS_DIAM_OUT_PRM ) )
|
|
|
|
setErrorLevel( PHYS_DIAM_OUT_PRM, TRANSLINE_ERROR );
|
2011-08-05 19:53:42 +00:00
|
|
|
else
|
2020-08-07 00:09:33 +00:00
|
|
|
setErrorLevel( PHYS_DIAM_OUT_PRM, TRANSLINE_WARNING );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( m_parameters[PHYS_DIAM_IN_PRM] > m_parameters[PHYS_DIAM_OUT_PRM] )
|
|
|
|
{
|
|
|
|
if( isSelected( PHYS_DIAM_IN_PRM ) )
|
|
|
|
setErrorLevel( PHYS_DIAM_IN_PRM, TRANSLINE_ERROR );
|
|
|
|
else if( isSelected( PHYS_DIAM_OUT_PRM ) )
|
|
|
|
setErrorLevel( PHYS_DIAM_OUT_PRM, TRANSLINE_ERROR );
|
|
|
|
}
|
|
|
|
|
|
|
|
if( !std::isfinite( m_parameters[PHYS_LEN_PRM] ) || m_parameters[PHYS_LEN_PRM] < 0.0 )
|
|
|
|
{
|
|
|
|
setErrorLevel( PHYS_LEN_PRM, TRANSLINE_ERROR );
|
|
|
|
}
|
|
|
|
// Check for warnings
|
|
|
|
if( !std::isfinite( m_parameters[Z0_PRM] ) || m_parameters[Z0_PRM] < 0 )
|
|
|
|
{
|
|
|
|
setErrorLevel( Z0_PRM, TRANSLINE_WARNING );
|
2011-08-05 19:53:42 +00:00
|
|
|
}
|
|
|
|
|
2020-08-07 00:09:33 +00:00
|
|
|
if( !std::isfinite( m_parameters[ANG_L_PRM] ) || m_parameters[ANG_L_PRM] < 0 )
|
|
|
|
{
|
|
|
|
setErrorLevel( ANG_L_PRM, TRANSLINE_WARNING );
|
|
|
|
}
|
|
|
|
}
|
2011-08-05 19:53:42 +00:00
|
|
|
|
|
|
|
|
2020-08-07 00:09:33 +00:00
|
|
|
#define MAX_ERROR 0.000001
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------
|
|
|
|
void TWISTEDPAIR::calcSynthesize()
|
|
|
|
{
|
|
|
|
if( isSelected( PHYS_DIAM_IN_PRM ) )
|
|
|
|
minimizeZ0Error1D( &( m_parameters[PHYS_DIAM_IN_PRM] ) );
|
|
|
|
else
|
|
|
|
minimizeZ0Error1D( &( m_parameters[PHYS_DIAM_OUT_PRM] ) );
|
2011-08-05 19:53:42 +00:00
|
|
|
}
|