2022-12-29 14:02:25 +00:00
|
|
|
/*
|
|
|
|
* This program source code file is part of KICAD, a free EDA CAD application.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2011 jean-pierre.charras
|
|
|
|
* Copyright (C) 1992-2022 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 <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* see
|
|
|
|
* http://www.desmith.net/NMdS/Electronics/TraceWidth.html
|
|
|
|
* http://www.ultracad.com/articles/pcbtemp.pdf
|
|
|
|
* for more info
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <calculator_panels/panel_eseries.h>
|
|
|
|
#include <pcb_calculator_settings.h>
|
|
|
|
#include <string_utils.h>
|
|
|
|
#include <wx/msgdlg.h>
|
|
|
|
|
|
|
|
#include <i18n_utility.h> // For _HKI definition in eseries_help.h
|
|
|
|
wxString eseries_help =
|
|
|
|
#include "eseries_help.h"
|
|
|
|
|
|
|
|
|
|
|
|
extern double DoubleFromString( const wxString& TextValue );
|
|
|
|
|
|
|
|
PANEL_E_SERIES::PANEL_E_SERIES( wxWindow* parent, wxWindowID id, const wxPoint& pos,
|
|
|
|
const wxSize& size, long style, const wxString& name ) :
|
|
|
|
PANEL_E_SERIES_BASE( parent, id, pos, size, style, name )
|
|
|
|
{
|
|
|
|
m_reqResUnits->SetLabel( wxT( "kΩ" ) );
|
|
|
|
m_exclude1Units->SetLabel( wxT( "kΩ" ) );
|
|
|
|
m_exclude2Units->SetLabel( wxT( "kΩ" ) );
|
|
|
|
|
2022-12-29 14:17:21 +00:00
|
|
|
wxSize minSize = m_ResRequired->GetMinSize();
|
|
|
|
int minWidth = m_ResRequired->GetTextExtent( wxT( "XXX.XXX" ) ).GetWidth();
|
|
|
|
|
|
|
|
m_ResRequired->SetMinSize( wxSize( minWidth, minSize.GetHeight() ) );
|
|
|
|
m_ResExclude1->SetMinSize( wxSize( minWidth, minSize.GetHeight() ) );
|
|
|
|
m_ResExclude2->SetMinSize( wxSize( minWidth, minSize.GetHeight() ) );
|
|
|
|
|
|
|
|
minSize = m_ESeriesError2R->GetMinSize();
|
|
|
|
minWidth = m_ESeriesError2R->GetTextExtent( wxT( "XX" ) + _( "Exact" ) ).GetWidth();
|
|
|
|
|
|
|
|
m_ESeriesError2R->SetMinSize( wxSize( minWidth, minSize.GetHeight() ) );
|
|
|
|
m_ESeriesError3R->SetMinSize( wxSize( minWidth, minSize.GetHeight() ) );
|
|
|
|
m_ESeriesError4R->SetMinSize( wxSize( minWidth, minSize.GetHeight() ) );
|
|
|
|
|
2022-12-29 14:02:25 +00:00
|
|
|
// show markdown formula explanation in lower help panel
|
|
|
|
wxString msg;
|
|
|
|
ConvertMarkdown2Html( wxGetTranslation( eseries_help ), msg );
|
|
|
|
m_panelESeriesHelp->SetPage( msg );
|
|
|
|
|
|
|
|
// Needed on wxWidgets 3.0 to ensure sizers are correctly set
|
|
|
|
GetSizer()->SetSizeHints( this );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PANEL_E_SERIES::~PANEL_E_SERIES()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PANEL_E_SERIES::ThemeChanged()
|
|
|
|
{
|
|
|
|
// Update the HTML window with the help text
|
|
|
|
m_panelESeriesHelp->ThemeChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PANEL_E_SERIES::SaveSettings( PCB_CALCULATOR_SETTINGS* aCfg )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PANEL_E_SERIES::LoadSettings( PCB_CALCULATOR_SETTINGS* aCfg )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PANEL_E_SERIES::OnCalculateESeries( wxCommandEvent& event )
|
|
|
|
{
|
|
|
|
double reqr; // required resistor stored in local copy
|
|
|
|
double error, err3 = 0;
|
|
|
|
wxString es, fs; // error and formula strings
|
|
|
|
|
|
|
|
wxBusyCursor dummy;
|
|
|
|
|
|
|
|
reqr = ( 1000 * DoubleFromString( m_ResRequired->GetValue() ) );
|
|
|
|
m_eSeries.SetRequiredValue( reqr ); // keep a local copy of required resistor value
|
|
|
|
m_eSeries.NewCalc(); // assume all values available
|
|
|
|
/*
|
|
|
|
* Exclude itself. For the case, a value from the available series is found as required value,
|
|
|
|
* the calculator assumes this value needs a replacement for the reason of being not available.
|
|
|
|
* Two further exclude values can be entered to exclude and are skipped as not being available.
|
|
|
|
* All values entered in KiloOhms are converted to Ohm for internal calculation
|
|
|
|
*/
|
|
|
|
m_eSeries.Exclude( 1000 * DoubleFromString( m_ResRequired->GetValue()));
|
|
|
|
m_eSeries.Exclude( 1000 * DoubleFromString( m_ResExclude1->GetValue()));
|
|
|
|
m_eSeries.Exclude( 1000 * DoubleFromString( m_ResExclude2->GetValue()));
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
m_eSeries.Calculate();
|
|
|
|
}
|
|
|
|
catch (std::out_of_range const& exc)
|
|
|
|
{
|
|
|
|
wxString msg;
|
|
|
|
msg << "Internal error: " << exc.what();
|
|
|
|
|
|
|
|
wxMessageBox( msg );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
fs = m_eSeries.GetResults()[S2R].e_name; // show 2R solution formula string
|
|
|
|
m_ESeries_Sol2R->SetValue( fs );
|
|
|
|
error = reqr + m_eSeries.GetResults()[S2R].e_value; // absolute value of solution
|
|
|
|
error = ( reqr / error - 1 ) * 100; // error in percent
|
|
|
|
|
|
|
|
if( error )
|
|
|
|
{
|
|
|
|
if( std::abs( error ) < 0.01 )
|
|
|
|
es.Printf( "<%.2f", 0.01 );
|
|
|
|
else
|
|
|
|
es.Printf( "%+.2f",error);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
es = _( "Exact" );
|
|
|
|
}
|
|
|
|
|
|
|
|
m_ESeriesError2R->SetValue( es ); // anyway show 2R error string
|
|
|
|
|
|
|
|
if( m_eSeries.GetResults()[S3R].e_use ) // if 3R solution available
|
|
|
|
{
|
|
|
|
err3 = reqr + m_eSeries.GetResults()[S3R].e_value; // calculate the 3R
|
|
|
|
err3 = ( reqr / err3 - 1 ) * 100; // error in percent
|
|
|
|
|
|
|
|
if( err3 )
|
|
|
|
{
|
|
|
|
if( std::abs( err3 ) < 0.01 )
|
|
|
|
es.Printf( "<%.2f", 0.01 );
|
|
|
|
else
|
|
|
|
es.Printf( "%+.2f",err3);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
es = _( "Exact" );
|
|
|
|
}
|
|
|
|
|
|
|
|
m_ESeriesError3R->SetValue( es ); // show 3R error string
|
|
|
|
fs = m_eSeries.GetResults()[S3R].e_name;
|
|
|
|
m_ESeries_Sol3R->SetValue( fs ); // show 3R formula string
|
|
|
|
}
|
|
|
|
else // nothing better than 2R found
|
|
|
|
{
|
|
|
|
fs = _( "Not worth using" );
|
|
|
|
m_ESeries_Sol3R->SetValue( fs );
|
|
|
|
m_ESeriesError3R->SetValue( wxEmptyString );
|
|
|
|
}
|
|
|
|
|
|
|
|
fs = wxEmptyString;
|
|
|
|
|
|
|
|
if( m_eSeries.GetResults()[S4R].e_use ) // show 4R solution if available
|
|
|
|
{
|
|
|
|
fs = m_eSeries.GetResults()[S4R].e_name;
|
|
|
|
|
|
|
|
error = reqr + m_eSeries.GetResults()[S4R].e_value; // absolute value of solution
|
|
|
|
error = ( reqr / error - 1 ) * 100; // error in percent
|
|
|
|
|
|
|
|
if( error )
|
|
|
|
es.Printf( "%+.2f",error );
|
|
|
|
else
|
|
|
|
es = _( "Exact" );
|
|
|
|
|
|
|
|
m_ESeriesError4R->SetValue( es );
|
|
|
|
}
|
|
|
|
else // no 4R solution
|
|
|
|
{
|
|
|
|
fs = _( "Not worth using" );
|
|
|
|
es = wxEmptyString;
|
|
|
|
m_ESeriesError4R->SetValue( es );
|
|
|
|
}
|
|
|
|
|
|
|
|
m_ESeries_Sol4R->SetValue( fs );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PANEL_E_SERIES::OnESeriesSelection( wxCommandEvent& event )
|
|
|
|
{
|
|
|
|
if( event.GetEventObject() == m_e1 )
|
|
|
|
m_eSeries.SetSeries( E1 );
|
|
|
|
else if( event.GetEventObject() == m_e3 )
|
|
|
|
m_eSeries.SetSeries( E3 );
|
|
|
|
else if( event.GetEventObject() == m_e12 )
|
|
|
|
m_eSeries.SetSeries( E12 );
|
|
|
|
else if( event.GetEventObject() == m_e24 )
|
|
|
|
m_eSeries.SetSeries( E24 );
|
|
|
|
else
|
|
|
|
m_eSeries.SetSeries( E6 );
|
|
|
|
}
|