diff --git a/pcb_calculator/CMakeLists.txt b/pcb_calculator/CMakeLists.txt
index b9fdb3144d..bd764c55f7 100644
--- a/pcb_calculator/CMakeLists.txt
+++ b/pcb_calculator/CMakeLists.txt
@@ -26,6 +26,8 @@ set( PCB_CALCULATOR_SRCS
calculator_panels/panel_electrical_spacing_base.cpp
calculator_panels/panel_eserie.cpp
calculator_panels/panel_eserie_base.cpp
+ calculator_panels/panel_fusing_current.cpp
+ calculator_panels/panel_fusing_current_base.cpp
calculator_panels/panel_regulator.cpp
calculator_panels/panel_regulator_base.cpp
calculator_panels/panel_track_width.cpp
@@ -214,6 +216,7 @@ endfunction()
md_doc2h( ${CMAKE_CURRENT_SOURCE_DIR}/attenuators/tee_formula )
md_doc2h( ${CMAKE_CURRENT_SOURCE_DIR}/tracks_width_versus_current_formula )
md_doc2h( ${CMAKE_CURRENT_SOURCE_DIR}/eserie_help )
+ md_doc2h( ${CMAKE_CURRENT_SOURCE_DIR}/fusing_current_help )
set( DOCS_LIST
${CMAKE_CURRENT_SOURCE_DIR}/attenuators/pi_formula.h
@@ -222,6 +225,7 @@ set( DOCS_LIST
${CMAKE_CURRENT_SOURCE_DIR}/attenuators/splitter_formula.h
${CMAKE_CURRENT_SOURCE_DIR}/tracks_width_versus_current_formula.h
${CMAKE_CURRENT_SOURCE_DIR}/eserie_help.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/fusing_current_help.h
)
set_source_files_properties( attenuators/attenuator_classes.cpp
diff --git a/pcb_calculator/calculator_panels/panel_fusing_current.cpp b/pcb_calculator/calculator_panels/panel_fusing_current.cpp
new file mode 100644
index 0000000000..17d403faf2
--- /dev/null
+++ b/pcb_calculator/calculator_panels/panel_fusing_current.cpp
@@ -0,0 +1,232 @@
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2021 Kicad Developers, see AUTHORS.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 3
+ * 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, see .
+ */
+
+// See equation 9b in this paper:
+// https://adam-research.de/pdfs/TRM_WhitePaper10_AdiabaticWire.pdf
+
+// See equation 8
+//https://scholar.google.com/scholar?hl=en&as_sdt=0%2C5&q=Fusing+of+wires+by+electrical+current&btnG=
+#define ABS_ZERO ( -273.15 )
+
+#include
+#include
+#include
+
+#include
+
+#include // For _HKI definition
+wxString fusing_current_help =
+#include "fusing_current_help.h"
+
+
+PANEL_FUSING_CURRENT::PANEL_FUSING_CURRENT( wxWindow * parent, wxWindowID id,
+ const wxPoint& pos, const wxSize& size,
+ long style, const wxString& name ) :
+PANEL_FUSING_CURRENT_BASE( parent, id, pos, size, style, name )
+{
+ // Set some defaults
+ wxString wxs( "" );
+ m_ambientValue->SetValue( wxString::Format( wxT( "%i" ), 25 ) );
+ m_meltingValue->SetValue( wxString::Format( wxT( "%i" ), 1084 ) ); // Value for copper
+ m_meltingValue->SetEditable( false ); // For now, this panel only works for copper.
+ m_widthValue->SetValue( wxString::Format( wxT( "%f" ), 0.1 ) );
+ m_thicknessValue->SetValue( wxString::Format( wxT( "%f" ), 0.035 ) );
+ m_currentValue->SetValue( wxString::Format( wxT( "%f" ), 10.0 ) );
+ m_timeValue->SetValue( wxString::Format( wxT( "%f" ), 0.01 ) );
+
+ // show markdown formula explanation in lower help panel
+ wxString msg;
+ ConvertMarkdown2Html( fusing_current_help, msg );
+ m_htmlHelp->SetPage( msg );
+
+ // Needed on wxWidgets 3.0 to ensure sizers are correctly set
+ GetSizer()->SetSizeHints( this );
+}
+
+
+PANEL_FUSING_CURRENT::~PANEL_FUSING_CURRENT()
+{
+}
+
+
+void PANEL_FUSING_CURRENT::ThemeChanged()
+{
+ // Update the HTML window with the help text
+ m_htmlHelp->ThemeChanged();
+}
+
+
+void PANEL_FUSING_CURRENT::m_onCalculateClick( wxCommandEvent& event )
+{
+ double Tm, Ta, I, W, T, time;
+ bool valid_Tm, valid_Ta, valid_I, valid_W, valid_T, valid_time;
+
+ valid_Tm = m_meltingValue->GetValue().ToDouble( &Tm );
+ valid_Ta = m_ambientValue->GetValue().ToDouble( &Ta );
+ valid_I = m_currentValue->GetValue().ToDouble( &I );
+ valid_W = m_widthValue->GetValue().ToDouble( &W );
+ valid_T = m_thicknessValue->GetValue().ToDouble( &T );
+ valid_time = m_timeValue->GetValue().ToDouble( &time );
+
+ double scalingT, scalingW;
+
+ scalingT = m_thicknessUnit->GetUnitScale();
+ scalingW = m_widthUnit->GetUnitScale();
+ T *= scalingT;
+ W *= scalingW;
+
+ valid_Tm &= std::isfinite( Tm );
+ valid_Ta &= std::isfinite( Ta );
+ valid_I &= std::isfinite( I );
+ valid_W &= std::isfinite( W );
+ valid_T &= std::isfinite( T );
+ valid_time &= std::isfinite( time );
+
+ if( valid_Tm && valid_Ta )
+ {
+ valid_Tm &= ( Tm > Ta );
+ valid_Ta &= ( Tm > Ta ) && ( Ta > ABS_ZERO );
+ }
+
+ valid_I &= ( I > 0 );
+ valid_W &= ( W > 0 );
+ valid_T &= ( T > 0 );
+ valid_time &= ( time > 0 );
+
+ double A = W * T;
+
+ // The energy required for copper to change phase ( fusion ) is 13.05 kJ / mol.
+ // Copper molar mass is 0.06355 kg/mol
+ // => The copper energy required for the phase change is 205.35 kJ / kg
+
+ double latentHeat = 205350.0;
+
+ // The change in enthalpy is deltaH = deltaU + delta P * deltaV
+ // with U the internal energy, P the pressure and V the volume
+ // But for constant pressure, the change in enthalpy is simply the thermal energy
+
+ // Copper specific heat energy is 0.385 kJ / kg / K.
+ // The change in heat energy is then 0.385 kJ / kg per degree.
+
+ double cp = 385; // Heat capacity in J / kg / K
+ double deltaEnthalpy = ( Tm - Ta ) * cp;
+ double density = 8940; // Density of copper to kilogram per cubic meter;
+ double volumicEnergy = density * ( deltaEnthalpy + latentHeat );
+
+ // Equation (3) is equivalent to :
+ // VolumicEnergy * Volume = R * I^2 * t
+ // If we consider the resistivity of copper instead of its resistance:
+ // VolumicEnergy * Volume = resistivity * length / Area * I^2 * t
+ // For a unit length:
+ // VolumicEnergy * Area = resistivity / Area * I^2 * t
+ // We can rewrite it as:
+ // VolumicEnergy * ( Area / I )^2 / resistivity = t
+ // coeff * ( Area / I ) ^2 = t with coeff = VolumicEnergy / resistivity
+
+ // Copper resistivity at 20C ( 293K ) is 1.72e-8 ohm m
+ // Copper temperature coefficient is 0.00393 per degree
+
+ double Ra = ( ( Ta - ABS_ZERO - 293 ) * 0.00393 + 1 ) * 1.72e-8;
+ double Rm = ( ( Tm - ABS_ZERO - 293 ) * 0.00393 + 1 ) * 1.72e-8;
+
+ // Let's consider the average resistivity
+ double R = ( Rm + Ra ) / 2;
+ double coeff = volumicEnergy / R;
+
+ bool valid = valid_I && valid_W && valid_T && valid_Ta && valid_Tm && valid_time;
+
+ if( m_widthRadio->GetValue() )
+ {
+ if( valid )
+ {
+ A = I / sqrt( coeff / time );
+ W = A / T;
+ m_widthValue->SetValue( wxString::Format( wxT( "%f" ), W / scalingW ) );
+ }
+ else
+ {
+ m_widthValue->SetValue( _( "Error" ) );
+ }
+ }
+ else if( m_thicknessRadio->GetValue() )
+ {
+ if( valid )
+ {
+ A = I / sqrt( coeff / time );
+ T = A / W;
+ m_thicknessValue->SetValue( wxString::Format( wxT( "%f" ), T / scalingT ) );
+ }
+ else
+ {
+ m_thicknessValue->SetValue( _( "Error" ) );
+ }
+ }
+ else if( m_currentRadio->GetValue() )
+ {
+ if( valid )
+ {
+ I = A * sqrt( coeff / time );
+ m_currentValue->SetValue( wxString::Format( wxT( "%f" ), I ) );
+ }
+ else
+ {
+ m_currentValue->SetValue( _( "Error" ) );
+ }
+ }
+ else if( m_timeRadio->GetValue() )
+ {
+ if( valid )
+ {
+ time = coeff * A * A / I / I;
+ m_timeValue->SetValue( wxString::Format( wxT( "%f" ), time ) );
+ }
+ else
+ {
+ m_timeValue->SetValue( _( "Error" ) );
+ }
+ }
+ else
+ {
+ // What happened ??? an extra radio button ?
+ }
+
+ // Now let's check the validity domain using the formula from the paper.
+ // https://adam-research.de/pdfs/TRM_WhitePaper10_AdiabaticWire.pdf
+ // We approximate the track with a circle having the same area.
+
+ double r = sqrt( A / M_PI ); // radius in m;
+ double epsilon = 5.67e-8; // Stefan-Boltzmann constant in W / ( m^2 K^4 )
+ double sigma = 0.5; // Surface radiative emissivity ( no unit )
+ // sigma is according to paper, between polished and oxidized
+
+ double tmKelvin = Tm - ABS_ZERO;
+ double frad = 0.5 * ( tmKelvin + 293 ) * ( tmKelvin + 293 ) * ( tmKelvin + 293 );
+
+ double tau = cp * density * r / ( epsilon * sigma * frad * 2 );
+
+ if( 2 * time < tau )
+ {
+ m_comment->SetLabel( "" );
+ }
+ else
+ {
+ m_comment->SetLabel( _( "Current calculation is underestimated due to long fusing time."
+ ) );
+ }
+}
\ No newline at end of file
diff --git a/pcb_calculator/calculator_panels/panel_fusing_current.h b/pcb_calculator/calculator_panels/panel_fusing_current.h
new file mode 100644
index 0000000000..40beed06c2
--- /dev/null
+++ b/pcb_calculator/calculator_panels/panel_fusing_current.h
@@ -0,0 +1,45 @@
+/*
+ * This program source code file is part of KICAD, a free EDA CAD application.
+ *
+ * Copyright (C) 1992-2021 Kicad Developers, see AUTHORS.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 3
+ * 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, see .
+ */
+
+#ifndef PANEL_FUSING_CURRENT_H
+#define PANEL_FUSING_CURRENT_H
+
+#include "panel_fusing_current_base.h"
+
+class PCB_CALCULATOR_SETTINGS;
+
+
+class PANEL_FUSING_CURRENT : public PANEL_FUSING_CURRENT_BASE
+{
+public:
+ PANEL_FUSING_CURRENT( wxWindow* parent, wxWindowID id = wxID_ANY,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL,
+ const wxString& name = wxEmptyString );
+ ~PANEL_FUSING_CURRENT();
+
+ // Methods from CALCULATOR_PANEL that must be overriden
+ void LoadSettings( PCB_CALCULATOR_SETTINGS* aCfg ) override {};
+ void SaveSettings( PCB_CALCULATOR_SETTINGS* aCfg ) override {};
+ void ThemeChanged() override;
+
+ void m_onCalculateClick( wxCommandEvent& event ) override;
+};
+
+#endif
diff --git a/pcb_calculator/calculator_panels/panel_fusing_current_base.cpp b/pcb_calculator/calculator_panels/panel_fusing_current_base.cpp
new file mode 100644
index 0000000000..063523cbc1
--- /dev/null
+++ b/pcb_calculator/calculator_panels/panel_fusing_current_base.cpp
@@ -0,0 +1,165 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version 3.10.1)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO *NOT* EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#include "widgets/unit_selector.h"
+
+#include "panel_fusing_current_base.h"
+
+///////////////////////////////////////////////////////////////////////////
+
+PANEL_FUSING_CURRENT_BASE::PANEL_FUSING_CURRENT_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : CALCULATOR_PANEL( parent, id, pos, size, style, name )
+{
+ wxBoxSizer* bSizer7;
+ bSizer7 = new wxBoxSizer( wxVERTICAL );
+
+ wxBoxSizer* bSizer8;
+ bSizer8 = new wxBoxSizer( wxVERTICAL );
+
+ wxStaticBoxSizer* m_parametersSizer;
+ m_parametersSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Parameters") ), wxVERTICAL );
+
+ wxFlexGridSizer* fgSizer11;
+ fgSizer11 = new wxFlexGridSizer( 0, 4, 0, 0 );
+ fgSizer11->SetFlexibleDirection( wxBOTH );
+ fgSizer11->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
+
+ m_dummy1 = new wxStaticText( m_parametersSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_dummy1->Wrap( -1 );
+ fgSizer11->Add( m_dummy1, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_ambientText = new wxStaticText( m_parametersSizer->GetStaticBox(), wxID_ANY, _("Ambient temperature:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ambientText->Wrap( -1 );
+ fgSizer11->Add( m_ambientText, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+
+ m_ambientValue = new wxTextCtrl( m_parametersSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer11->Add( m_ambientValue, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_ambientUnit = new wxStaticText( m_parametersSizer->GetStaticBox(), wxID_ANY, _("deg C"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_ambientUnit->Wrap( -1 );
+ fgSizer11->Add( m_ambientUnit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_dummy2 = new wxStaticText( m_parametersSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_dummy2->Wrap( -1 );
+ fgSizer11->Add( m_dummy2, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_meltingText = new wxStaticText( m_parametersSizer->GetStaticBox(), wxID_ANY, _("Melting point:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_meltingText->Wrap( -1 );
+ fgSizer11->Add( m_meltingText, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+
+ m_meltingValue = new wxTextCtrl( m_parametersSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer11->Add( m_meltingValue, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_meltingUnit = new wxStaticText( m_parametersSizer->GetStaticBox(), wxID_ANY, _("deg C"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_meltingUnit->Wrap( -1 );
+ fgSizer11->Add( m_meltingUnit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_widthRadio = new wxRadioButton( m_parametersSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer11->Add( m_widthRadio, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_widthText = new wxStaticText( m_parametersSizer->GetStaticBox(), wxID_ANY, _("Track width:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_widthText->Wrap( -1 );
+ fgSizer11->Add( m_widthText, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+
+ m_widthValue = new wxTextCtrl( m_parametersSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer11->Add( m_widthValue, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ wxArrayString m_widthUnitChoices;
+ m_widthUnit = new UNIT_SELECTOR_LEN( m_parametersSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_widthUnitChoices, 0 );
+ m_widthUnit->SetSelection( 0 );
+ fgSizer11->Add( m_widthUnit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_thicknessRadio = new wxRadioButton( m_parametersSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer11->Add( m_thicknessRadio, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_thicknessText = new wxStaticText( m_parametersSizer->GetStaticBox(), wxID_ANY, _("Track thickness:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_thicknessText->Wrap( -1 );
+ fgSizer11->Add( m_thicknessText, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+
+ m_thicknessValue = new wxTextCtrl( m_parametersSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer11->Add( m_thicknessValue, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ wxArrayString m_thicknessUnitChoices;
+ m_thicknessUnit = new UNIT_SELECTOR_THICKNESS( m_parametersSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, m_thicknessUnitChoices, 0 );
+ m_thicknessUnit->SetSelection( 0 );
+ fgSizer11->Add( m_thicknessUnit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_currentRadio = new wxRadioButton( m_parametersSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer11->Add( m_currentRadio, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_currentText = new wxStaticText( m_parametersSizer->GetStaticBox(), wxID_ANY, _("Current:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_currentText->Wrap( -1 );
+ fgSizer11->Add( m_currentText, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+
+ m_currentValue = new wxTextCtrl( m_parametersSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer11->Add( m_currentValue, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_currentUnit = new wxStaticText( m_parametersSizer->GetStaticBox(), wxID_ANY, _("A"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_currentUnit->Wrap( -1 );
+ fgSizer11->Add( m_currentUnit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+ m_timeRadio = new wxRadioButton( m_parametersSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer11->Add( m_timeRadio, 0, wxALL, 5 );
+
+ m_timeText = new wxStaticText( m_parametersSizer->GetStaticBox(), wxID_ANY, _("Time to fuse:"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_timeText->Wrap( -1 );
+ fgSizer11->Add( m_timeText, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT|wxALL, 5 );
+
+ m_timeValue = new wxTextCtrl( m_parametersSizer->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ fgSizer11->Add( m_timeValue, 0, wxALL, 5 );
+
+ m_timeUnit = new wxStaticText( m_parametersSizer->GetStaticBox(), wxID_ANY, _("s"), wxDefaultPosition, wxDefaultSize, 0 );
+ m_timeUnit->Wrap( -1 );
+ fgSizer11->Add( m_timeUnit, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+
+
+ m_parametersSizer->Add( fgSizer11, 2, wxEXPAND, 5 );
+
+
+ bSizer8->Add( m_parametersSizer, 0, wxALL, 5 );
+
+ wxBoxSizer* bSizer3;
+ bSizer3 = new wxBoxSizer( wxHORIZONTAL );
+
+ m_calculateButton = new wxButton( this, wxID_ANY, _("Calculate"), wxDefaultPosition, wxDefaultSize, 0 );
+ bSizer3->Add( m_calculateButton, 0, wxALL, 5 );
+
+ m_comment = new wxStaticText( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
+ m_comment->Wrap( -1 );
+ bSizer3->Add( m_comment, 0, wxALIGN_CENTER|wxALL, 5 );
+
+
+ bSizer8->Add( bSizer3, 0, wxEXPAND, 5 );
+
+ wxStaticBoxSizer* m_helpSizer;
+ m_helpSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Help") ), wxVERTICAL );
+
+ m_htmlHelp = new HTML_WINDOW( m_helpSizer->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_AUTO );
+ m_htmlHelp->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOWTEXT ) );
+ m_htmlHelp->SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) );
+
+ m_helpSizer->Add( m_htmlHelp, 1, wxEXPAND|wxLEFT|wxRIGHT|wxTOP, 5 );
+
+
+ bSizer8->Add( m_helpSizer, 1, wxALL|wxEXPAND, 5 );
+
+
+ bSizer7->Add( bSizer8, 1, wxEXPAND, 5 );
+
+
+ this->SetSizer( bSizer7 );
+ this->Layout();
+
+ // Connect Events
+ m_calculateButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_FUSING_CURRENT_BASE::m_onCalculateClick ), NULL, this );
+}
+
+PANEL_FUSING_CURRENT_BASE::~PANEL_FUSING_CURRENT_BASE()
+{
+ // Disconnect Events
+ m_calculateButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_FUSING_CURRENT_BASE::m_onCalculateClick ), NULL, this );
+
+}
diff --git a/pcb_calculator/calculator_panels/panel_fusing_current_base.fbp b/pcb_calculator/calculator_panels/panel_fusing_current_base.fbp
new file mode 100644
index 0000000000..cfbcd72405
--- /dev/null
+++ b/pcb_calculator/calculator_panels/panel_fusing_current_base.fbp
@@ -0,0 +1,1824 @@
+
+
+
+
+
diff --git a/pcb_calculator/calculator_panels/panel_fusing_current_base.h b/pcb_calculator/calculator_panels/panel_fusing_current_base.h
new file mode 100644
index 0000000000..8cd0219bd9
--- /dev/null
+++ b/pcb_calculator/calculator_panels/panel_fusing_current_base.h
@@ -0,0 +1,86 @@
+///////////////////////////////////////////////////////////////////////////
+// C++ code generated with wxFormBuilder (version 3.10.0-4761b0c5)
+// http://www.wxformbuilder.org/
+//
+// PLEASE DO *NOT* EDIT THIS FILE!
+///////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+#include
+#include
+#include
+class UNIT_SELECTOR_LEN;
+class UNIT_SELECTOR_THICKNESS;
+
+#include "html_window.h"
+#include "calculator_panels/calculator_panel.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+///////////////////////////////////////////////////////////////////////////
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// Class PANEL_FUSING_CURRENT_BASE
+///////////////////////////////////////////////////////////////////////////////
+class PANEL_FUSING_CURRENT_BASE : public CALCULATOR_PANEL
+{
+ private:
+
+ protected:
+ wxStaticText* m_dummy1;
+ wxStaticText* m_ambientText;
+ wxTextCtrl* m_ambientValue;
+ wxStaticText* m_ambientUnit;
+ wxStaticText* m_dummy2;
+ wxStaticText* m_meltingText;
+ wxTextCtrl* m_meltingValue;
+ wxStaticText* m_meltingUnit;
+ wxRadioButton* m_widthRadio;
+ wxStaticText* m_widthText;
+ wxTextCtrl* m_widthValue;
+ UNIT_SELECTOR_LEN* m_widthUnit;
+ wxRadioButton* m_thicknessRadio;
+ wxStaticText* m_thicknessText;
+ wxTextCtrl* m_thicknessValue;
+ UNIT_SELECTOR_THICKNESS* m_thicknessUnit;
+ wxRadioButton* m_currentRadio;
+ wxStaticText* m_currentText;
+ wxTextCtrl* m_currentValue;
+ wxStaticText* m_currentUnit;
+ wxRadioButton* m_timeRadio;
+ wxStaticText* m_timeText;
+ wxTextCtrl* m_timeValue;
+ wxStaticText* m_timeUnit;
+ wxButton* m_calculateButton;
+ wxStaticText* m_comment;
+ HTML_WINDOW* m_htmlHelp;
+
+ // Virtual event handlers, override them in your derived class
+ virtual void m_onCalculateClick( wxCommandEvent& event ) { event.Skip(); }
+
+
+ public:
+
+ PANEL_FUSING_CURRENT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 512,574 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );
+
+ ~PANEL_FUSING_CURRENT_BASE();
+
+};
+
diff --git a/pcb_calculator/fusing_current_help.h b/pcb_calculator/fusing_current_help.h
new file mode 100644
index 0000000000..702f51e41e
--- /dev/null
+++ b/pcb_calculator/fusing_current_help.h
@@ -0,0 +1,6 @@
+// Do not edit this file, it is autogenerated by CMake from the .md file
+_HKI( "You can use the this calculator to check if a small track can handle a large current for a short period of time.\n"
+"This tool allows you to design a track fuse but should be used as an estimate only.\n"
+"\n"
+"The calculator estimates the energy required to heat the wire up to its melting point as well as the energy required for the change of phase.\n"
+"This energy is then compared to the one dissipated by the wire resistance." );
diff --git a/pcb_calculator/fusing_current_help.md b/pcb_calculator/fusing_current_help.md
new file mode 100644
index 0000000000..1e9c7b3725
--- /dev/null
+++ b/pcb_calculator/fusing_current_help.md
@@ -0,0 +1,5 @@
+You can use the this calculator to check if a small track can handle a large current for a short period of time.
+This tool allows you to design a track fuse but should be used as an estimate only.
+
+The calculator estimates the energy required to heat the wire up to its melting point as well as the energy required for the change of phase.
+This energy is then compared to the one dissipated by the wire resistance.
\ No newline at end of file
diff --git a/pcb_calculator/pcb_calculator_frame.cpp b/pcb_calculator/pcb_calculator_frame.cpp
index b3a76d5dd5..d83a4a86bc 100644
--- a/pcb_calculator/pcb_calculator_frame.cpp
+++ b/pcb_calculator/pcb_calculator_frame.cpp
@@ -39,6 +39,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -87,6 +88,9 @@ PCB_CALCULATOR_FRAME::PCB_CALCULATOR_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
_( "Via Size" ) );
AddCalculator( new PANEL_TRACK_WIDTH( m_treebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ),
_( "Track Width" ) );
+ AddCalculator( new PANEL_FUSING_CURRENT( m_treebook, wxID_ANY, wxDefaultPosition, wxDefaultSize,
+ wxTAB_TRAVERSAL ),
+ _( "Fusing Current" ) );
AddCalculator( new PANEL_CABLE_SIZE( m_treebook, wxID_ANY, wxDefaultPosition, wxDefaultSize,
wxTAB_TRAVERSAL ),
_( "Cable Size" ) );