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 (C) 1992-2023 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 );
74
75 // Needed on wxWidgets 3.0 to ensure sizers are correctly set
76 GetSizer()->SetSizeHints( this );
77}
78
79
81{
82}
83
84
86{
87 // Update the HTML window with the help text
89}
90
91
93{
94}
95
96
98{
99}
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 {
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 )
174 else if( event.GetEventObject() == m_e3 )
176 else if( event.GetEventObject() == m_e12 )
178 else if( event.GetEventObject() == m_e24 )
180 else
182}
const char * name
Definition: DXF_plotter.cpp:57
bool SetPage(const wxString &aSource) override
Definition: html_window.cpp:50
void ThemeChanged()
Definition: html_window.cpp:75
Class PANEL_R_CALCULATOR_BASE.
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.
void Exclude(double aValue)
If any value of the selected E-series not available, it can be entered as an exclude value.
const std::array< std::optional< RESISTANCE >, NUMBER_OF_LEVELS > & GetResults()
Accessor to calculation results.
void SetSeries(uint32_t aSeries)
Set E-series to be used in calculations.
void Calculate()
Executes all the calculations.
void NewCalc(double aTargetValue)
Initialize next calculation, clear exclusion mask and erase results from previous calculation.
const int minSize
Push and Shove router track width and via size dialog.
#define _(s)
Some functions to handle hotkeys in KiCad.
@ E3
Definition: eseries.h:71
@ E24
Definition: eseries.h:74
@ E12
Definition: eseries.h:73
@ E6
Definition: eseries.h:72
@ E1
Definition: eseries.h:70
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:390
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)