Commit d80da9f1 authored by jean-pierre charras's avatar jean-pierre charras

Pcb calculator: add track width versus current and electrical spacing versus...

Pcb calculator: add track width versus current and electrical spacing versus voltage tools (from IPC 2221)
parents 4de4a208 4b0a9669
......@@ -8,11 +8,13 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}
set(PCB_CALCULATOR_SRCS
attenuators.cpp
board_classes_values.cpp
pcb_calculator.cpp
pcb_calculator_frame.cpp
colorcode.cpp
electrical_spacing_values.cpp
params_read_write.cpp
pcb_calculator.cpp
pcb_calculator_frame.cpp
regulators_funct.cpp
tracks_width_versus_current.cpp
transline_ident.cpp
UnitSelector.cpp
transline/transline.cpp
......@@ -24,8 +26,8 @@ set(PCB_CALCULATOR_SRCS
transline/stripline.cpp
transline/twistedpair.cpp
transline_dlg_funct.cpp
dialogs/pcb_calculator_frame_base.cpp
attenuators/attenuator_classes.cpp
dialogs/pcb_calculator_frame_base.cpp
)
if(WIN32)
......
......@@ -27,6 +27,11 @@ public:
* to normalized units (meter, herz, ohm, radian )
*/
virtual double GetUnitScale() = 0;
wxString GetUnitName()
{
return GetStringSelection();
}
};
class UNIT_SELECTOR_LEN: public UNIT_SELECTOR
......
......@@ -78,18 +78,18 @@ void PCB_CALCULATOR_FRAME::TransfAttenuatorDataToPanel()
{
wxString msg;
msg.Printf( wxT( "%f" ), m_currAttenuator->m_Attenuation );
msg.Printf( wxT( "%g" ), m_currAttenuator->m_Attenuation );
m_AttValueCtrl->SetValue( msg );
m_AttValueCtrl->Enable( m_currAttenuator->m_Attenuation_Enable );
m_ZinValueCtrl->Enable( m_currAttenuator->m_Zin_Enable );
if( m_currAttenuator->m_Zin_Enable )
msg.Printf( wxT( "%f" ), m_currAttenuator->m_Zin );
msg.Printf( wxT( "%g" ), m_currAttenuator->m_Zin );
else
msg.Clear();;
m_ZinValueCtrl->SetValue( msg );
msg.Printf( wxT( "%f" ), m_currAttenuator->m_Zout );
msg.Printf( wxT( "%g" ), m_currAttenuator->m_Zout );
m_ZoutValueCtrl->SetValue( msg );
}
......@@ -114,15 +114,15 @@ void PCB_CALCULATOR_FRAME::TransfAttenuatorResultsToPanel()
return;
}
msg.Printf( wxT( "%f" ), m_currAttenuator->m_R1 );
msg.Printf( wxT( "%g" ), m_currAttenuator->m_R1 );
m_Att_R1_Value->SetValue( msg );
msg.Printf( wxT( "%f" ), m_currAttenuator->m_R2 );
msg.Printf( wxT( "%g" ), m_currAttenuator->m_R2 );
m_Att_R2_Value->SetValue( msg );
if( m_currAttenuator->m_ResultCount < 3 )
m_Att_R3_Value->SetValue( wxEmptyString );
else
{
msg.Printf( wxT( "%f" ), m_currAttenuator->m_R3 );
msg.Printf( wxT( "%g" ), m_currAttenuator->m_R3 );
m_Att_R3_Value->SetValue( msg );
}
}
......
......@@ -98,41 +98,43 @@ void PCB_CALCULATOR_FRAME::OnBoardClassesUnitsSelection( wxCommandEvent& event )
void PCB_CALCULATOR_FRAME::BoardClassesUpdateData( double aUnitScale )
{
wxString txt;
#define FMT wxT("%g")
#define NOVAL wxT("--")
for( int ii = 0; ii < BRDCLASS_COUNT; ii ++ )
{
// Display min tracks width
if( clist[ii].m_Lines > -1.0 )
txt.Printf( wxT("%f"), clist[ii].m_Lines / aUnitScale);
txt.Printf( FMT, clist[ii].m_Lines / aUnitScale);
else
txt = wxT("--");
txt = NOVAL;
m_gridClassesValuesDisplay->SetCellValue(0, ii, txt );
// Display min clearance
if( clist[ii].m_Clearance > -1.0 )
txt.Printf( wxT("%f"), clist[ii].m_Clearance / aUnitScale);
txt.Printf( FMT, clist[ii].m_Clearance / aUnitScale);
else
txt = wxT("--");
txt = NOVAL;
m_gridClassesValuesDisplay->SetCellValue(1, ii, txt );
// Display min Via diam diff
if( clist[ii].m_ViaDiamDiff > -1.0 )
txt.Printf( wxT("%f"), clist[ii].m_ViaDiamDiff / aUnitScale);
txt.Printf( FMT, clist[ii].m_ViaDiamDiff / aUnitScale);
else
txt = wxT("--");
txt = NOVAL;
m_gridClassesValuesDisplay->SetCellValue(2, ii, txt );
// Display min Pad diam diff (plated)
if( clist[ii].m_PadDiamDiffPlated > -1.0 )
txt.Printf( wxT("%f"), clist[ii].m_PadDiamDiffPlated / aUnitScale);
txt.Printf( FMT, clist[ii].m_PadDiamDiffPlated / aUnitScale);
else
txt = wxT("--");
txt = NOVAL;
m_gridClassesValuesDisplay->SetCellValue(3, ii, txt );
// Display min Pad diam diff (non plated)
if( clist[ii].m_PadDiamDiffNotPlated > -1.0 )
txt.Printf( wxT("%f"), clist[ii].m_PadDiamDiffNotPlated / aUnitScale);
txt.Printf( FMT, clist[ii].m_PadDiamDiffNotPlated / aUnitScale);
else
txt = wxT("--");
txt = NOVAL;
m_gridClassesValuesDisplay->SetCellValue(4, ii, txt );
}
}
......
......@@ -33,11 +33,12 @@ class UNIT_SELECTOR_RESISTOR;
#include <wx/textctrl.h>
#include <wx/button.h>
#include <wx/panel.h>
#include <wx/radiobox.h>
#include <wx/statline.h>
#include <wx/choice.h>
#include <wx/html/htmlwin.h>
#include <wx/statbox.h>
#include <wx/statline.h>
#include <wx/grid.h>
#include <wx/radiobox.h>
#include <wx/notebook.h>
#include <wx/frame.h>
......@@ -75,6 +76,61 @@ class PCB_CALCULATOR_FRAME_BASE : public wxFrame
wxStaticText* m_unitsVout;
wxButton* m_buttonCalculate;
wxStaticText* m_RegulMessage;
wxPanel* m_panelTrackWidth;
wxStaticText* m_staticTextTW_WarningMessage;
wxStaticText* m_staticTextCurrent;
wxTextCtrl* m_TrackCurrentValue;
wxStaticText* m_staticText62;
wxStaticText* m_staticText63;
wxTextCtrl* m_TrackDeltaTValue;
wxStaticText* m_staticText64;
wxStaticText* m_staticText65;
wxTextCtrl* m_TrackThicknessValue;
UNIT_SELECTOR_LEN* m_TW_CuThickness_choiceUnit;
wxStaticText* m_staticText66;
wxTextCtrl* m_TrackLengthValue;
UNIT_SELECTOR_LEN* m_TW_CuLength_choiceUnit;
wxHtmlWindow* m_htmlWinFormulas;
wxButton* m_buttonTW;
wxStaticText* m_staticTextWidth;
wxTextCtrl* m_ExtTrackWidthValue;
UNIT_SELECTOR_LEN* m_TW_ExtTrackWidth_choiceUnit;
wxStaticText* m_staticTextArea;
wxTextCtrl* m_ExtTrackAreaValue;
wxStaticText* m_ExtTrackAreaUnitLabel;
wxStaticText* m_staticText651;
wxTextCtrl* m_ExtTrackResistValue;
wxStaticText* m_staticText84;
wxStaticText* m_staticText661;
wxTextCtrl* m_ExtTrackVDropValue;
wxStaticText* m_staticText83;
wxStaticText* m_staticText79;
wxTextCtrl* m_ExtTrackLossValue;
wxStaticText* m_staticText791;
wxStaticText* m_staticTextWidth11;
wxTextCtrl* m_IntTrackWidthValue;
UNIT_SELECTOR_LEN* m_TW_IntTrackWidth_choiceUnit;
wxStaticText* m_staticTextArea1;
wxTextCtrl* m_IntTrackAreaValue;
wxStaticText* m_IntTrackAreaUnitLabel;
wxStaticText* m_staticText6511;
wxTextCtrl* m_IntTrackResistValue;
wxStaticText* m_staticText841;
wxStaticText* m_staticText6611;
wxTextCtrl* m_IntTrackVDropValue;
wxStaticText* m_staticText831;
wxStaticText* m_staticText792;
wxTextCtrl* m_IntTrackLossValue;
wxStaticText* m_staticText7911;
wxPanel* m_panelElectricalSpacing;
UNIT_SELECTOR_LEN* m_ElectricalSpacingUnitsSelector;
wxStaticLine* m_staticline2;
wxStaticText* m_staticText891;
wxTextCtrl* m_ElectricalSpacingVoltage;
wxButton* m_buttonElectSpacingRefresh;
wxStaticText* m_staticTextElectricalSpacing;
wxGrid* m_gridElectricalSpacingValues;
wxStaticText* m_staticText88;
wxPanel* m_panelTransline;
wxRadioBox* m_TranslineSelection;
wxPanel* m_panelDisplayshape;
......@@ -195,6 +251,9 @@ class PCB_CALCULATOR_FRAME_BASE : public wxFrame
// Virtual event handlers, overide them in your derived class
virtual void OnRegulatorCalcButtonClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnTWCalculateButt( wxCommandEvent& event ) { event.Skip(); }
virtual void OnElectricalSpacingUnitsSelection( wxCommandEvent& event ) { event.Skip(); }
virtual void OnElectricalSpacingRefresh( wxCommandEvent& event ) { event.Skip(); }
virtual void OnTranslineSelection( wxCommandEvent& event ) { event.Skip(); }
virtual void OnPaintTranslinePanel( wxPaintEvent& event ) { event.Skip(); }
virtual void OnTranslineEpsilonR_Button( wxCommandEvent& event ) { event.Skip(); }
......@@ -212,7 +271,7 @@ class PCB_CALCULATOR_FRAME_BASE : public wxFrame
public:
PCB_CALCULATOR_FRAME_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Pcb Calculator"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 752,465 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL );
PCB_CALCULATOR_FRAME_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Pcb Calculator"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 670,465 ), long style = wxDEFAULT_FRAME_STYLE|wxRESIZE_BORDER|wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL );
~PCB_CALCULATOR_FRAME_BASE();
......
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2011 jean-pierre.charras
* Copyright (C) 2011 Kicad Developers, see change_log.txt for contributors.
*
* 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 program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <wx/app.h>
#include <wx/config.h>
#include "pcb_calculator_frame_base.h"
#include "pcb_calculator.h"
#include "UnitSelector.h"
#include "units_scales.h"
extern double ReturnDoubleFromString( const wxString& TextValue );
#define VALUE_COUNT 7
#define CLASS_COUNT 10
/* These values come from IPC2221
* there are 10 voltage classes:
* "0 ... 15V" "16 ... 30V" "31 ... 50V" "51 ... 100V"
* "101 ... 150V" "151 ... 170V" "171 ... 250V"
* "251 ... 300V" "301 ... 500V" " > 500V"
* and for each voltage class
* there ar e 7 cases:
* "B1" "B2" "B3" "B4" "A5" "A6" "A7"
* B1 - Internal Conductors
* B2 - External Conductors, uncoated, sea level to 3050 m
* B3 - External Conductors, uncoated, over 3050 m
* B4 - External Conductors, with permanent polymer coating (any elevation)
* A5 - External Conductors, with conformal coating over assembly (any elevation)
* A6 - External Component lead/termination, uncoated
* A7 - External Component lead termination, with conformal coating (any elevation)
*/
/* For voltages greater than 500V, the (per volt) table values
* must be added to the 500V values. For example, the elec-
* trical spacing for a Type B1 board with 600V is calculated
* as:
* 600V - 500V = 100V
* 0.25 mm + (100V x 0.0025
*/
static double clist[CLASS_COUNT][VALUE_COUNT] =
{
{ 0.05 * UNIT_MM, 0.1 * UNIT_MM, 0.1 * UNIT_MM, 0.05 * UNIT_MM, 0.13 * UNIT_MM, 0.13 *
UNIT_MM,
0.13 * UNIT_MM }, // 0 ... 15V
{ 0.05 * UNIT_MM, 0.1 * UNIT_MM, 0.1 * UNIT_MM, 0.05 * UNIT_MM, 0.13 * UNIT_MM, 0.25 *
UNIT_MM,
0.13 * UNIT_MM }, // 16 ... 30V
{ 0.1 * UNIT_MM, 0.6 * UNIT_MM, 0.6 * UNIT_MM, 0.13 * UNIT_MM, 0.13 * UNIT_MM, 0.4 *
UNIT_MM,
0.13 * UNIT_MM }, // 31 ... 50V
{ 0.1 * UNIT_MM, 0.6 * UNIT_MM, 1.5 * UNIT_MM, 0.13 * UNIT_MM, 0.13 * UNIT_MM, 0.5 *
UNIT_MM,
0.13 * UNIT_MM }, // 51 ... 100V
{ 0.2 * UNIT_MM, 0.6 * UNIT_MM, 3.2 * UNIT_MM, 0.4 * UNIT_MM, 0.4 * UNIT_MM, 0.8 *
UNIT_MM,
0.4 * UNIT_MM }, // 101 ... 150V
{ 0.2 * UNIT_MM, 1.25 * UNIT_MM, 3.2 * UNIT_MM, 0.4 * UNIT_MM, 0.4 * UNIT_MM, 0.8 *
UNIT_MM,
0.4 * UNIT_MM }, // 151 ... 170V
{ 0.2 * UNIT_MM, 1.25 * UNIT_MM, 6.4 * UNIT_MM, 0.4 * UNIT_MM, 0.4 * UNIT_MM, 0.8 *
UNIT_MM,
0.4 * UNIT_MM }, // 171 ... 250V
{ 0.2 * UNIT_MM, 1.25 * UNIT_MM, 12.5 * UNIT_MM, 0.4 * UNIT_MM, 0.4 * UNIT_MM, 0.8 *
UNIT_MM,
0.8 * UNIT_MM }, // 251 ... 300V
{ 0.25 * UNIT_MM, 2.5 * UNIT_MM, 12.5 * UNIT_MM, 0.8 * UNIT_MM, 0.8 * UNIT_MM, 1.5 *
UNIT_MM,
0.8 * UNIT_MM }, // 301 ... 500V
// These last values are used to calculate spacing for voltage > 500V
// there are not the spacing
{ 0.0025 * UNIT_MM, 0.005 * UNIT_MM, 0.025 * UNIT_MM, 0.00305 * UNIT_MM,
0.00305 * UNIT_MM, 0.00305 * UNIT_MM, 0.00305 * UNIT_MM }, // > 500V
};
void PCB_CALCULATOR_FRAME::OnElectricalSpacingUnitsSelection( wxCommandEvent& event )
{
ElectricalSpacingUpdateData( m_ElectricalSpacingUnitsSelector->GetUnitScale() );
}
void PCB_CALCULATOR_FRAME::OnElectricalSpacingRefresh( wxCommandEvent& event )
{
ElectricalSpacingUpdateData( m_ElectricalSpacingUnitsSelector->GetUnitScale() );
}
void PCB_CALCULATOR_FRAME::ElectricalSpacingUpdateData( double aUnitScale )
{
wxString txt;
double voltage = 500.0; // to calculate values at V > 500V
txt = m_ElectricalSpacingVoltage->GetValue();
if( ! txt.IsEmpty() )
voltage = ReturnDoubleFromString(txt);
if( voltage < 500.0 )
voltage = 500.0;
txt.Printf( wxT( "%g" ), voltage );
m_ElectricalSpacingVoltage->SetValue( txt );
for( int ii = 0; ii < CLASS_COUNT-1; ii++ )
{
for( int jj = 0; jj < VALUE_COUNT; jj++ )
{
txt.Printf( wxT( "%g" ), clist[ii][jj] / aUnitScale );
m_gridElectricalSpacingValues->SetCellValue( ii, jj, txt );
}
}
for( int jj = 0; jj < VALUE_COUNT; jj++ )
{
double spacing = clist[CLASS_COUNT-2][jj];
double spacing_extra = clist[CLASS_COUNT-1][jj];
spacing += spacing_extra * ( voltage - 500.0 );
txt.Printf( wxT( "%g" ), spacing / aUnitScale );
m_gridElectricalSpacingValues->SetCellValue( CLASS_COUNT-1, jj, txt );
}
}
......@@ -46,6 +46,37 @@ private:
void ReadConfig();
void WriteConfig();
// tracks width versus current functions:
/**
* Function OnTWCalculateButt
* Called by clicking on the calculate button
*/
void OnTWCalculateButt( wxCommandEvent& event );
/**
* Function TW_Init
* Read config and init dialog widgets values
*/
void TW_Init();
/**
* Function TW_WriteConfig
* Write Track width prameters in config
*/
void TW_WriteConfig();
/**
* Function TWCalculate
* Performs track caracteristics values calculations.
*/
double TWCalculate( double aCurrent, double aThickness, double aDeltaT_C,
bool aUseInternalLayer );
// Electrical spacing panel:
void OnElectricalSpacingUnitsSelection( wxCommandEvent& event );
void OnElectricalSpacingRefresh( wxCommandEvent& event );
void ElectricalSpacingUpdateData( double aUnitScale );
// Transline functions:
/**
* Function OnTranslineSelection
......
......@@ -38,6 +38,8 @@
#define KEYWORD_COLORCODE_SELECTION wxT( "CC_selection" )
#define KEYWORD_ATTENUATORS_SELECTION wxT( "Att_selection" )
#define KEYWORD_BRDCLASS_SELECTION wxT( "BrdClass_selection" )
#define KEYWORD_ELECTRICAL_SPACING_SELECTION wxT( "ElectSpacing_selection" )
#define KEYWORD_ELECTRICAL_SPACING_VOLTAGE wxT( "ElectSpacing_voltage" )
#define KEYWORD_REGUL_R1 wxT( "RegulR1" )
#define KEYWORD_REGUL_R2 wxT( "RegulR2" )
#define KEYWORD_REGUL_VREF wxT( "RegulVREF" )
......@@ -73,12 +75,16 @@ PCB_CALCULATOR_FRAME::PCB_CALCULATOR_FRAME( wxWindow * parent ) :
TranslineTypeSelection( m_currTransLineType );
m_TranslineSelection->SetSelection( m_currTransLineType );
TW_Init();
SetAttenuator( m_AttenuatorsSelection->GetSelection() );
ToleranceSelection( m_rbToleranceSelection->GetSelection() );
BoardClassesUpdateData( m_BoardClassesUnitsSelector->GetUnitScale() );
ElectricalSpacingUpdateData( m_ElectricalSpacingUnitsSelector->GetUnitScale() );
#ifdef __WINDOWS__
SetIcon( wxICON( pcb_calculator_icon ) );
#else
......@@ -142,6 +148,10 @@ void PCB_CALCULATOR_FRAME::ReadConfig()
m_RegulVrefValue->SetValue( msg );
m_Config->Read( KEYWORD_REGUL_VOUT, &msg, wxT("12") );
m_RegulVoutValue->SetValue( msg );
m_Config->Read( KEYWORD_ELECTRICAL_SPACING_SELECTION, &ltmp, 0 );
m_ElectricalSpacingUnitsSelector->SetSelection( ltmp );
m_Config->Read( KEYWORD_ELECTRICAL_SPACING_VOLTAGE, &msg, wxT("500") );
m_ElectricalSpacingVoltage->SetValue( msg );
for( unsigned ii = 0; ii < m_transline_list.size(); ii++ )
m_transline_list[ii]->ReadConfig( m_Config );
......@@ -174,6 +184,12 @@ void PCB_CALCULATOR_FRAME::WriteConfig()
m_Config->Write( KEYWORD_REGUL_R2, m_RegulR2Value->GetValue() );
m_Config->Write( KEYWORD_REGUL_VREF, m_RegulVrefValue->GetValue() );
m_Config->Write( KEYWORD_REGUL_VOUT, m_RegulVoutValue->GetValue() );
m_Config->Write( KEYWORD_ELECTRICAL_SPACING_SELECTION,
m_ElectricalSpacingUnitsSelector->GetSelection() );
m_Config->Write( KEYWORD_ELECTRICAL_SPACING_VOLTAGE,
m_ElectricalSpacingVoltage->GetValue() );
TW_WriteConfig();
for( unsigned ii = 0; ii < m_transline_list.size(); ii++ )
m_transline_list[ii]->WriteConfig( m_Config );
......
......@@ -105,13 +105,13 @@ void PCB_CALCULATOR_FRAME::RegulatorsSolve()
break;
}
// write values to panel:
txt.Printf(wxT("%f"), r1);
txt.Printf(wxT("%g"), r1);
m_RegulR1Value->SetValue(txt);
txt.Printf(wxT("%f"), r2);
txt.Printf(wxT("%g"), r2);
m_RegulR2Value->SetValue(txt);
txt.Printf(wxT("%f"), vref);
txt.Printf(wxT("%g"), vref);
m_RegulVrefValue->SetValue(txt);
txt.Printf(wxT("%f"), vout);
txt.Printf(wxT("%g"), vout);
m_RegulVoutValue->SetValue(txt);
}
......
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2011 jean-pierre.charras
* Copyright (C) 1992-2011 Kicad Developers, see change_log.txt for contributors.
*
* 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 program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/* see
* http://www.desmith.net/NMdS/Electronics/TraceWidth.html
* http://www.ultracad.com/articles/pcbtemp.pdf
* for more info
*/
#include "wx/wx.h"
#include "wx/config.h"
#include "pcb_calculator_frame_base.h"
#include "pcb_calculator.h"
#include "UnitSelector.h"
#include "units_scales.h"
extern double ReturnDoubleFromString( const wxString& TextValue );
// Key words to read/write some parameters in config:
#define KEYWORD_TW_CURRENT wxT( "TW_Track_Current" )
#define KEYWORD_TW_DELTA_TC wxT( "TW_Delta_TC" )
#define KEYWORD_TW_TRACK_COPPER_THICKNESS wxT( "TW_Track_CopperThickness" )
#define KEYWORD_TW_TRACK_LEN wxT( "TW_Track_Len" )
#define KEYWORD_TW_TRACK_COPPER_THICKNESS_UNIT wxT( "TW_Track_CopperThickness_Unit" )
#define KEYWORD_TW_TRACK_LEN_UNIT wxT( "TW_Track_Len_Unit" )
#define KEYWORD_TW_EXTTRACK_WIDTH_UNIT wxT( "TW_ExtTrack_Width_Unit" )
#define KEYWORD_TW_INTTRACK_WIDTH_UNIT wxT( "TW_IntTrack_Width_Unit" )
void PCB_CALCULATOR_FRAME::TW_WriteConfig()
{
// Save current parameters values in config:
m_Config->Write( KEYWORD_TW_EXTTRACK_WIDTH_UNIT, m_TW_ExtTrackWidth_choiceUnit->GetSelection() );
m_Config->Write( KEYWORD_TW_INTTRACK_WIDTH_UNIT, m_TW_IntTrackWidth_choiceUnit->GetSelection() );
m_Config->Write( KEYWORD_TW_TRACK_COPPER_THICKNESS_UNIT,
m_TW_CuThickness_choiceUnit->GetSelection() );
m_Config->Write( KEYWORD_TW_TRACK_LEN_UNIT, m_TW_CuLength_choiceUnit->GetSelection() );
m_Config->Write( KEYWORD_TW_CURRENT, m_TrackCurrentValue->GetValue() );
m_Config->Write( KEYWORD_TW_DELTA_TC, m_TrackDeltaTValue->GetValue() );
m_Config->Write( KEYWORD_TW_TRACK_COPPER_THICKNESS, m_TrackThicknessValue->GetValue() );
m_Config->Write( KEYWORD_TW_TRACK_LEN, m_TrackLengthValue->GetValue() );
}
void PCB_CALCULATOR_FRAME::OnTWCalculateButt( wxCommandEvent& event )
{
// Prepare parameters:
double current = ReturnDoubleFromString( m_TrackCurrentValue->GetValue() );
double thickness = ReturnDoubleFromString( m_TrackThicknessValue->GetValue() );
double deltaT_C = ReturnDoubleFromString( m_TrackDeltaTValue->GetValue() );
double track_len = ReturnDoubleFromString( m_TrackLengthValue->GetValue() );
double extTrackWidth;
double intTrackWidth;
// Normalize units:
thickness *= m_TW_CuThickness_choiceUnit->GetUnitScale();
track_len *= m_TW_CuLength_choiceUnit->GetUnitScale();
extTrackWidth = TWCalculate( current, thickness, deltaT_C, false );
intTrackWidth = TWCalculate( current, thickness, deltaT_C, true );
// Display values:
wxString msg;
msg.Printf( wxT( "%g" ), extTrackWidth / m_TW_ExtTrackWidth_choiceUnit->GetUnitScale() );
m_ExtTrackWidthValue->SetValue( msg );
msg.Printf( wxT( "%g" ), intTrackWidth / m_TW_IntTrackWidth_choiceUnit->GetUnitScale() );
m_IntTrackWidthValue->SetValue( msg );
// Display areas:
double scale = m_TW_ExtTrackWidth_choiceUnit->GetUnitScale();
double ext_area = thickness * extTrackWidth;
msg.Printf( wxT( "%g" ), ext_area / (scale * scale) );
m_ExtTrackAreaValue->SetValue( msg );
wxString strunit = m_TW_ExtTrackWidth_choiceUnit->GetUnitName();
msg = strunit + wxT( " x " ) + strunit;
m_ExtTrackAreaUnitLabel->SetLabel( msg );
scale = m_TW_IntTrackWidth_choiceUnit->GetUnitScale();
double int_area = thickness * intTrackWidth;
msg.Printf( wxT( "%g" ), int_area / (scale * scale) );
m_IntTrackAreaValue->SetValue( msg );
strunit = m_TW_IntTrackWidth_choiceUnit->GetUnitName();
msg = strunit + wxT( " x " ) + strunit;
m_IntTrackAreaUnitLabel->SetLabel( msg );
// Display resistance (assuming using copper ):
double rho = 1.72e-008; // In Ohms*meter
double ext_res = rho / ext_area * track_len;
msg.Printf( wxT( "%g" ), ext_res );
m_ExtTrackResistValue->SetValue( msg );
double int_res = rho / int_area * track_len;
msg.Printf( wxT( "%g" ), int_res );
m_IntTrackResistValue->SetValue( msg );
// Display drop voltage
double ext_drop_volt = ext_res * current;
msg.Printf( wxT( "%g" ), ext_drop_volt );
m_ExtTrackVDropValue->SetValue( msg );
double int_drop_volt = int_res * current;
msg.Printf( wxT( "%g" ), int_drop_volt );
m_IntTrackVDropValue->SetValue( msg );
// Display power loss
double loss = ext_drop_volt * current;
msg.Printf( wxT( "%g" ), loss );
m_ExtTrackLossValue->SetValue( msg );
loss = int_drop_volt * current;
msg.Printf( wxT( "%g" ), loss );
m_IntTrackLossValue->SetValue( msg );
}
/* calculate track width for external or internal layers
*
* Imax = 0.048 * dT^0.44 * A^0.725 for external layer
* Imax = 0.024 * dT^0.44 * A^0.725 for internal layer
* with A = area = aThickness * trackWidth ( in mils )
* and dT = temperature rise in degree C
* Of course we want to know trackWidth
*/
double PCB_CALCULATOR_FRAME::TWCalculate( double aCurrent, double aThickness, double aDeltaT_C,
bool aUseInternalLayer )
{
double scale = 0.048; // We are using normalize units (sizes in meters)
if( aUseInternalLayer )
scale *= 0.024 / 0.048;
// aThickness is given in normalize units (in meters) and we need mil
aThickness /= UNIT_MIL;
/* formula is Imax = scale * dT^0.44 * A^0.725
* or
* log(Imax) = log(scale) + 0.44*log(dT)
* +(0.725*(log(aThickness) + log(trackWidth))
* log(trackWidth) * 0.725 = ln(Imax) - ln(scale) - 0.44*log(dT) - 0.725*log(aThickness)
*/
double dtmp = log( aCurrent ) - log( scale ) - 0.44 * log( aDeltaT_C ) - 0.725 * log( aThickness );
dtmp /= 0.725;
double trackWidth = exp( dtmp );
trackWidth *= UNIT_MIL; // We are using normalize units (sizes in meters) and we have mil
return trackWidth; // in meters
}
void PCB_CALCULATOR_FRAME::TW_Init()
{
int tmp;
wxString msg;
// Read parameters values:
m_Config->Read( KEYWORD_TW_EXTTRACK_WIDTH_UNIT, &tmp, 0 );
m_TW_ExtTrackWidth_choiceUnit->SetSelection( tmp );
m_Config->Read( KEYWORD_TW_INTTRACK_WIDTH_UNIT, &tmp, 0 );
m_TW_IntTrackWidth_choiceUnit->SetSelection( tmp );
m_Config->Read( KEYWORD_TW_TRACK_COPPER_THICKNESS_UNIT, &tmp, 0 );
m_TW_CuThickness_choiceUnit->SetSelection( tmp );
m_Config->Read( KEYWORD_TW_TRACK_LEN_UNIT, &tmp, 0 );
m_TW_CuLength_choiceUnit->SetSelection( tmp );
m_Config->Read( KEYWORD_TW_CURRENT, &msg, wxT( "1.0" ) );
m_TrackCurrentValue->SetValue( msg );
m_Config->Read( KEYWORD_TW_DELTA_TC, &msg, wxT( "10.0" ) );
m_TrackDeltaTValue->SetValue( msg );
m_Config->Read( KEYWORD_TW_TRACK_COPPER_THICKNESS, &msg, wxT( "0.035" ) );
m_TrackThicknessValue->SetValue( msg );
m_Config->Read( KEYWORD_TW_TRACK_LEN, &msg, wxT( "20" ) );
m_TrackLengthValue->SetValue( msg );
// Init formulas text
m_htmlWinFormulas->AppendToPage( _( "<br><em>The formula (from IPC 2221) is:</em></br>" ) );
m_htmlWinFormulas->AppendToPage( _( "<br><b>I = K * dT<sup>0.44</sup> * (W*H)<sup>0.725</sup></b></br>" ) );
m_htmlWinFormulas->AppendToPage( _( "<br>Internal traces : <b>K = 0.024</b></br>" ) );
m_htmlWinFormulas->AppendToPage( _( "<br>External traces: <b>K = 0.048</b></br>" ) );
m_htmlWinFormulas->AppendToPage( _( "<br>where:</br>" ) );
m_htmlWinFormulas->AppendToPage( _( "<br><b>I</b> = maximum current in Amps</br>" ) );
m_htmlWinFormulas->AppendToPage( _( "<br><b>dT</b> = temperature rise above ambient in deg C</br>" ) );
m_htmlWinFormulas->AppendToPage( _( "<br><b>W,H</b> = Width and Thickness in mils</br>" ) );
}
......@@ -250,9 +250,9 @@ TRANSLINE_IDENT::TRANSLINE_IDENT( enum transline_type_id aType )
_( "MurC" ), _( "Relative Permeability of Conductor" ), 1,
false ) );
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_S_PRM,
_( "a" ), _( "Width of Waveguide" ), 10.0, true ) );
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_WIDTH_PRM,
_( "a" ), _( "Width of Waveguide" ), 10.0, true ) );
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_S_PRM,
_( "b" ), _( "Height of Waveguide" ), 5.0, true ) );
AddPrm( new TRANSLINE_PRM( PRM_TYPE_PHYS, PHYS_LEN_PRM,
_( "L" ), _( "Waveguide Length" ), 50.0, true ) );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment