KiCad PCB EDA Suite
Loading...
Searching...
No Matches
panel_r_calculator.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 (C) 2011 jean-pierre.charras
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 3
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21/* see
22 * http://www.desmith.net/NMdS/Electronics/TraceWidth.html
23 * http://www.ultracad.com/articles/pcbtemp.pdf
24 * for more info
25 */
26
29#include <string_utils.h>
30#include <wx/msgdlg.h>
31#include <eseries.h>
33
34#include <i18n_utility.h> // For _HKI definition in r_calculator_help.h
36#include "r_calculator_help.h"
37
38/* RES_EQUIV_CALC class considers resistor values from a limited range
39 * and only combinations of up to 4 resistors, so target values less than
40 * parallel combination of minimum resistors or greater than serial combination
41 * of maximum resistors cannot be reasonably looked for
42 */
43static const double min_target_value = static_cast<double>(RES_EQUIV_CALC_FIRST_VALUE) / 4;
44static const double max_target_value = static_cast<double>(RES_EQUIV_CALC_LAST_VALUE) * 4;
45
46extern double DoubleFromString( const wxString& TextValue );
47
48PANEL_R_CALCULATOR::PANEL_R_CALCULATOR( wxWindow* parent, wxWindowID id, const wxPoint& pos,
49 const wxSize& size, long style, const wxString& name ) :
50 PANEL_R_CALCULATOR_BASE( parent, id, pos, size, style, name )
51{
52 m_reqResUnits->SetLabel( wxT( "kΩ" ) );
53 m_exclude1Units->SetLabel( wxT( "kΩ" ) );
54 m_exclude2Units->SetLabel( wxT( "kΩ" ) );
55
56 wxSize minSize = m_ResRequired->GetMinSize();
57 int minWidth = m_ResRequired->GetTextExtent( wxT( "XXX.XXX" ) ).GetWidth();
58
59 m_ResRequired->SetMinSize( wxSize( minWidth, minSize.GetHeight() ) );
60 m_ResExclude1->SetMinSize( wxSize( minWidth, minSize.GetHeight() ) );
61 m_ResExclude2->SetMinSize( wxSize( minWidth, minSize.GetHeight() ) );
62
63 minSize = m_ESeriesError2R->GetMinSize();
64 minWidth = m_ESeriesError2R->GetTextExtent( wxT( "XX" ) + _( "Exact" ) ).GetWidth();
65
66 m_ESeriesError2R->SetMinSize( wxSize( minWidth, minSize.GetHeight() ) );
67 m_ESeriesError3R->SetMinSize( wxSize( minWidth, minSize.GetHeight() ) );
68 m_ESeriesError4R->SetMinSize( wxSize( minWidth, minSize.GetHeight() ) );
69
70 // show markdown formula explanation in lower help panel
71 wxString msg;
72 ConvertMarkdown2Html( wxGetTranslation( r_calculator_help ), msg );
73 m_panelESeriesHelp->SetPage( msg );
74
75 // Needed on wxWidgets 3.0 to ensure sizers are correctly set
76 GetSizer()->SetSizeHints( this );
77}
78
79
83
84
86{
87 // Update the HTML window with the help text
88 m_panelESeriesHelp->ThemeChanged();
89}
90
91
95
96
100
101
102void PANEL_R_CALCULATOR::OnCalculateESeries( wxCommandEvent& event )
103{
104 double reqr = 1000 * DoubleFromString( m_ResRequired->GetValue() );
105
106 if( std::isnan( reqr ) || reqr < min_target_value || reqr > max_target_value )
107 {
108 wxMessageBox( wxString::Format( _( "Incorrect required resistance value: %s" ),
109 m_ResRequired->GetValue() ) );
110 return;
111 }
112
113 wxBusyCursor busyCursor; // As long as this variable exists, the cursor will be 'busy'
114
115 m_eSeries.NewCalc( reqr ); // assume all values available
116 /*
117 * Exclude itself. For the case, a value from the available series is found as required value,
118 * the calculator assumes this value needs a replacement for the reason of being not available.
119 * Two further exclude values can be entered to exclude and are skipped as not being available.
120 * All values entered in KiloOhms are converted to Ohm for internal calculation
121 */
122 m_eSeries.Exclude( reqr );
123 m_eSeries.Exclude( 1000 * DoubleFromString( m_ResExclude1->GetValue() ) );
124 m_eSeries.Exclude( 1000 * DoubleFromString( m_ResExclude2->GetValue() ) );
125
126 try
127 {
128 m_eSeries.Calculate();
129 }
130 catch( const std::exception& exc )
131 {
132 wxMessageBox( wxString::Format( "Internal error: %s", exc.what() ) );
133 return;
134 }
135
136 auto showResult = [reqr]( const std::optional<RESISTANCE>& aResult, wxTextCtrl* aFormulaField,
137 wxTextCtrl* aErrorField )
138 {
139 wxString fs, es; // formula and error string
140
141 if( aResult ) // if value is present
142 {
143 fs = aResult->name;
144 double sol = aResult->value;
145 double error = ( sol / reqr - 1 ) * 100; // relative error in percent
146
147 if( std::abs( error ) < epsilon )
148 es = _( "Exact" );
149 else if( std::abs( error ) < 0.01 )
150 es.Printf( "<%.2f", 0.01 );
151 else
152 es.Printf( "%+.2f", error );
153 }
154 else
155 {
156 fs = _( "Not worth using" );
157 es = wxEmptyString;
158 }
159
160 aFormulaField->SetValue( fs );
161 aErrorField->SetValue( es );
162 };
163
167}
168
169
170void PANEL_R_CALCULATOR::OnESeriesSelection( wxCommandEvent& event )
171{
172 if( event.GetEventObject() == m_e1 )
173 m_eSeries.SetSeries( ESERIES::E1 );
174 else if( event.GetEventObject() == m_e3 )
175 m_eSeries.SetSeries( ESERIES::E3 );
176 else if( event.GetEventObject() == m_e12 )
177 m_eSeries.SetSeries( ESERIES::E12 );
178 else if( event.GetEventObject() == m_e24 )
179 m_eSeries.SetSeries( ESERIES::E24 );
180 else
181 m_eSeries.SetSeries( ESERIES::E6 );
182}
const char * name
PANEL_R_CALCULATOR_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)
PANEL_R_CALCULATOR(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL, const wxString &name=wxEmptyString)
void OnCalculateESeries(wxCommandEvent &event) override
Called on calculate button and executes all E-series calculations.
void LoadSettings(PCB_CALCULATOR_SETTINGS *aCfg) override
Load the settings into the panel.
void ThemeChanged() override
Update UI elements of the panel when the theme changes to ensure the images and fonts/colors are appr...
RES_EQUIV_CALC m_eSeries
void OnESeriesSelection(wxCommandEvent &event) override
Radio Buttons to select the E-series for the resistor calculator.
void SaveSettings(PCB_CALCULATOR_SETTINGS *aCfg) override
Save the settings from the panel.
const int minSize
Push and Shove router track width and via size dialog.
#define _(s)
Some functions to handle hotkeys in KiCad.
@ E24
Definition eseries.h:74
@ E12
Definition eseries.h:73
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:400
double DoubleFromString(const wxString &TextValue)
static const double max_target_value
double DoubleFromString(const wxString &TextValue)
wxString r_calculator_help
#define RES_EQUIV_CALC_FIRST_VALUE
#define RES_EQUIV_CALC_LAST_VALUE
const double epsilon
void ConvertMarkdown2Html(const wxString &aMarkdownInput, wxString &aHtmlOutput)