KiCad PCB EDA Suite
Loading...
Searching...
No Matches
panel_via_size.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KICAD, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 3
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20/* All calculations are based on this [1] online calculator:
21 *
22 * References:
23 *
24 * [1]: The CircuitCalculator.com Blog - PCB Via Calculator
25 * http://circuitcalculator.com/wordpress/2006/03/12/pcb-via-calculator/
26 *
27 * [2]: Constructing Your Power Supply - Layout Considerations
28 * https://www.ti.com/seclit/ml/slup230/slup230.pdf
29 *
30 * [3]: Current Carrying Capacity of Vias - Some Conceptual Observations
31 * https://www.ultracad.com/articles/viacurrents.pdf
32 *
33 * [4]: IPC-2221A - Generic Standard on Printed Board Design
34 * http://www.sphere.bc.ca/class/downloads/ipc_2221a-pcb%20standards.pdf
35 *
36 * [5]: Copper - online catalogue source - Goodfellow
37 * http://www.goodfellow.com/E/Copper.html
38 *
39 * [6]: Thermal Conductivity of Metals, Metallic Elements and Alloys
40 * https://www.engineeringtoolbox.com/thermal-conductivity-metals-d_858.html
41 *
42 * [7]: Johnson & Graham, High Speed Digital Design: A Handbook of Black Magic
43 */
44
45#include <cmath>
46#include <wx/choicdlg.h>
47
48#include <bitmaps.h>
50#include <common_data.h>
53#include <units_scales.h>
54
55
56PANEL_VIA_SIZE::PANEL_VIA_SIZE( wxWindow* parent, wxWindowID id,
57 const wxPoint& pos, const wxSize& size,
58 long style, const wxString& name ) :
59 PANEL_VIA_SIZE_BASE( parent, id, pos, size, style, name )
60{
61 m_viaResistivityUnits->SetLabel( wxT( "Ω⋅m" ) );
62 m_viaTempUnits->SetLabel( wxT( "°C" ) );
63 m_viaResUnits->SetLabel( wxT( "Ω" ) );
64 m_viaThermalResUnits->SetLabel( wxT( "°C/W" ) );
65 m_viaReactanceUnits->SetLabel( wxT( "Ω" ) );
66
68
69 // Needed on wxWidgets 3.0 to ensure sizers are correctly set
70 GetSizer()->SetSizeHints( this );
71}
72
73
77
78
83
84
85void PANEL_VIA_SIZE::OnViaEpsilonR_Button( wxCommandEvent& event )
86{
87 //Shows a list of current relative dielectric constant(Er) and select a value.
88 wxArrayString list = StandardRelativeDielectricConstantList();
89
90 wxString value = wxGetSingleChoice( wxEmptyString, _( "Relative Dielectric Constants" ), list )
91 .BeforeFirst( ' ' );
92
93 if( !value.IsEmpty() )
94 m_textCtrlPlatingPermittivity->SetValue( value );
95}
96
97
98void PANEL_VIA_SIZE::OnViaRho_Button( wxCommandEvent& event )
99{
100 wxArrayString list = StandardResistivityList();
101
102 // Shows a list of current Specific resistance list (rho) and select a value
103 wxString value = wxGetSingleChoice( wxEmptyString, _( "Electrical Resistivity in Ohm*m" ),
104 list ).BeforeFirst( ' ' );
105
106 if( !value.IsEmpty() )
107 m_textCtrlPlatingResistivity->SetValue( value );
108}
109
110
111void PANEL_VIA_SIZE::onUpdateViaCalcErrorText( wxUpdateUIEvent& event )
112{
113 // Update the Error message if a via has a external diameter
114 // bigger than the clearance area diameter
115 // (therefore the via is inside a copper zone and some parameters cannot be calculated)
116 double clearanceDia = std::abs( DoubleFromString( m_textCtrlClearanceDia->GetValue() ) );
117 clearanceDia *= m_choiceClearanceDia->GetUnitScale();
118 double padDia = std::abs( DoubleFromString( m_textCtrlViaPadDia->GetValue() ) );
119 padDia *= m_choiceViaPadDia->GetUnitScale();
120
121 m_staticTextWarning->Show( clearanceDia <= padDia );
122}
123
124
125void PANEL_VIA_SIZE::OnViaResetButtonClick( wxCommandEvent& event )
126{
127 #define DEFAULT_UNIT_SEL_MM 0
128 #define DEFAULT_UNIT_SEL_OHM 0
129
130 m_textCtrlHoleDia->SetValue( wxString::Format( "%g", 0.4 ) );
131 m_choiceHoleDia->SetSelection( DEFAULT_UNIT_SEL_MM );
132 m_textCtrlPlatingThickness->SetValue( wxString::Format( "%g", 0.035 ) );
134 m_textCtrlViaLength->SetValue( wxString::Format( "%g", 1.6 ) );
135 m_choiceViaLength->SetSelection( DEFAULT_UNIT_SEL_MM );
136 m_textCtrlViaPadDia->SetValue( wxString::Format( "%g", 0.6 ) );
137 m_choiceViaPadDia->SetSelection( DEFAULT_UNIT_SEL_MM );
138 m_textCtrlClearanceDia->SetValue( wxString::Format( "%g", 1.0 ) );
140 m_textCtrlImpedance->SetValue( wxString::Format( "%g", 50.0 ) );
142 m_textCtrlAppliedCurrent->SetValue( wxString::Format( "%g", 1.0 ) );
143 m_textCtrlPlatingResistivity->SetValue( wxString::Format( "%g", 1.72e-8 ) );
144 m_textCtrlPlatingPermittivity->SetValue( wxString::Format( "%g", 4.5 ) );
145 m_textCtrlTemperatureDiff->SetValue( wxString::Format( "%g", 10.0 ) );
146 m_textCtrlRiseTime->SetValue( wxString::Format( "%g", 1.0 ) );
147}
148
149
176
177
198
199
200void PANEL_VIA_SIZE::OnViaCalculate( wxCommandEvent& event )
201{
202 // Load parameters
203 double finishedHoleDia = std::abs( DoubleFromString( m_textCtrlHoleDia->GetValue() ) );
204 double platingThickness = std::abs( DoubleFromString( m_textCtrlPlatingThickness->GetValue() ) );
205 double viaLength = std::abs( DoubleFromString( m_textCtrlViaLength->GetValue() ) );
206 double padDia = std::abs( DoubleFromString( m_textCtrlViaPadDia->GetValue() ) );
207 double clearanceDia = std::abs( DoubleFromString( m_textCtrlClearanceDia->GetValue() ) );
208 double charImpedance = std::abs( DoubleFromString( m_textCtrlImpedance->GetValue() ) );
209 double appliedCurrent = std::abs( DoubleFromString( m_textCtrlAppliedCurrent->GetValue() ) );
210 double platingResistivity = std::abs( DoubleFromString( m_textCtrlPlatingResistivity->GetValue() ) );
211 double relativePermitivity = std::abs( DoubleFromString( m_textCtrlPlatingPermittivity->GetValue() ) );
212 double temperatureDiff = std::abs( DoubleFromString( m_textCtrlTemperatureDiff->GetValue() ) );
213 double pulseRiseTime = std::abs( DoubleFromString( m_textCtrlRiseTime->GetValue() ) );
214
215 // Normalize units
216 finishedHoleDia *= m_choiceHoleDia->GetUnitScale();
217 platingThickness *= m_choicePlatingThickness->GetUnitScale();
218 viaLength *= m_choiceViaLength->GetUnitScale();
219 padDia *= m_choiceViaPadDia->GetUnitScale();
220 clearanceDia *= m_choiceClearanceDia->GetUnitScale();
221 charImpedance *= m_choiceImpedance->GetUnitScale();
222 // platingResistivity is ok: it is in Ohm*m in tables
223
224 // Calculate cross-sectional area of the via's cylindrical structure [3]
225 double area = M_PI * ( finishedHoleDia + platingThickness ) * platingThickness; // m^2
226
227 double viaResistance = platingResistivity * viaLength / area; // Ohms
228
229 // Using thermal resistivity value 2.49e-3 meter-Kelvin/Watt, equivalent to
230 // thermal conductivity of 401 Watt/(meter-Kelvin) [5][6]
231 const double thermalResistivity = 2.49e-3; // m K/W
232 double thermalResistance = thermalResistivity * viaLength / area; // deg C/W
233
234 double voltageDrop = appliedCurrent * viaResistance;
235
236 double powerLoss = appliedCurrent * voltageDrop;
237
238 // Estimate current carrying capacity of the via
239 // See comment #17 in [1] for a brief discussion on the formula
240 // This formula from IPC-2221 [4] is also used in the Track Width calculator
241 area /= pow( UNIT_MIL, 2 ); // m^2 to mil^2
242 const double k = 0.048;
243 const double b = 0.44;
244 const double c = 0.725;
245 double estimatedAmpacity = k * pow( temperatureDiff, b ) * pow( area, c );
246
247 // Equation 7.6 in [7]
248 double capacitance = 55.51 * relativePermitivity * viaLength * padDia;
249 capacitance /= clearanceDia - padDia;
250
251 // Equation 7.8 in [7]
252 double timeDegradation = 2.2 * capacitance * charImpedance / 2;
253
254 // Equation 7.9 in [7]
255 double inductance = 200 * viaLength;
256 inductance *= log( 4 * viaLength / finishedHoleDia ) + 1;
257
258 // Equation 7.11 in [7]
259 double reactance = M_PI * inductance / pulseRiseTime;
260
261 // Update the display
262 VSDisplayValues( viaResistance, voltageDrop, powerLoss, estimatedAmpacity,
263 thermalResistance, capacitance, timeDegradation, inductance, reactance );
264}
265
266void PANEL_VIA_SIZE::VSDisplayValues( double aViaResistance, double aVoltageDrop, double aPowerLoss,
267 double aEstimatedAmpacity, double aThermalResistance,
268 double aCapacitance, double aTimeDegradation, double aInductance,
269 double aReactance )
270{
271 wxString msg;
272
273 msg.Printf( "%g", aViaResistance );
274 m_ViaResistance->SetLabel( msg );
275
276 msg.Printf( "%g", aVoltageDrop );
277 m_ViaVoltageDrop->SetLabel( msg );
278
279 msg.Printf( "%g", aPowerLoss );
280 m_ViaPowerLoss->SetLabel( msg );
281
282 msg.Printf( "%g", aEstimatedAmpacity );
283 m_ViaAmpacity->SetLabel( msg );
284
285 msg.Printf( "%g", aThermalResistance );
286 m_ViaThermalResistance->SetLabel( msg );
287
288 msg.Printf( "%g", aCapacitance );
289 m_ViaCapacitance->SetLabel( msg );
290
291 msg.Printf( "%g", aTimeDegradation );
292 m_RiseTimeOutput->SetLabel( msg );
293
294 msg.Printf( "%g", aInductance );
295 m_Inductance->SetLabel( msg );
296
297 msg.Printf( "%g", aReactance );
298 m_Reactance->SetLabel( msg );
299}
const char * name
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition bitmap.cpp:106
wxTextCtrl * m_textCtrlPlatingResistivity
wxTextCtrl * m_textCtrlClearanceDia
PANEL_VIA_SIZE_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxTAB_TRAVERSAL, const wxString &name=wxEmptyString)
wxStaticText * m_RiseTimeOutput
wxTextCtrl * m_textCtrlPlatingThickness
wxStaticText * m_staticTextWarning
UNIT_SELECTOR_LEN * m_choiceClearanceDia
wxStaticText * m_ViaThermalResistance
wxTextCtrl * m_textCtrlViaLength
wxTextCtrl * m_textCtrlAppliedCurrent
wxTextCtrl * m_textCtrlViaPadDia
wxTextCtrl * m_textCtrlRiseTime
wxStaticText * m_ViaAmpacity
wxStaticText * m_viaResUnits
wxTextCtrl * m_textCtrlImpedance
wxStaticText * m_viaReactanceUnits
UNIT_SELECTOR_LEN * m_choiceViaPadDia
wxStaticText * m_ViaCapacitance
UNIT_SELECTOR_RESISTOR * m_choiceImpedance
wxStaticText * m_ViaResistance
wxTextCtrl * m_textCtrlTemperatureDiff
wxStaticText * m_ViaVoltageDrop
wxTextCtrl * m_textCtrlPlatingPermittivity
wxStaticBitmap * m_viaBitmap
wxStaticText * m_viaResistivityUnits
UNIT_SELECTOR_LEN * m_choiceViaLength
UNIT_SELECTOR_LEN * m_choiceHoleDia
wxStaticText * m_viaTempUnits
wxStaticText * m_ViaPowerLoss
UNIT_SELECTOR_LEN * m_choicePlatingThickness
wxStaticText * m_viaThermalResUnits
void OnViaResetButtonClick(wxCommandEvent &event) override
Called when the user clicks the reset button; sets the parameters to their default values.
void SaveSettings(PCB_CALCULATOR_SETTINGS *aCfg) override
Save the settings from the panel.
void VSDisplayValues(double aViaResistance, double aVoltageDrop, double aPowerLoss, double aEstimatedAmpacity, double aThermalResistance, double aCapacitance, double aTimeDegradation, double aInductance, double aReactance)
Display the results of the calculation.
void ThemeChanged() override
Update UI elements of the panel when the theme changes to ensure the images and fonts/colors are appr...
void OnViaRho_Button(wxCommandEvent &event) override
Shows a list of current Specific resistance list (rho) and select a value.
void LoadSettings(PCB_CALCULATOR_SETTINGS *aCfg) override
Load the settings into the panel.
PANEL_VIA_SIZE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL, const wxString &name=wxEmptyString)
void OnViaEpsilonR_Button(wxCommandEvent &event) override
Shows a list of current relative dielectric constant(Er) and select a value.
void onUpdateViaCalcErrorText(wxUpdateUIEvent &event) override
Update the Error message in via calculation panel.
void OnViaCalculate(wxCommandEvent &event) override
Called when the user changes any value in the via calculator.
wxArrayString StandardResistivityList()
wxArrayString StandardRelativeDielectricConstantList()
#define _(s)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:411
#define DEFAULT_UNIT_SEL_OHM
#define DEFAULT_UNIT_SEL_MM
double DoubleFromString(const wxString &TextValue)
#define UNIT_MIL
#define M_PI