pcb_calculator, eserie rework and add E24 serie.
Numerous enhancements in code.
This commit is contained in:
parent
0533196294
commit
84e83fc743
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.0-4761b0c5)
|
||||
// C++ code generated with wxFormBuilder (version 3.10.0-39-g3487c3cb)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
@ -81,6 +81,9 @@ PANEL_E_SERIE_BASE::PANEL_E_SERIE_BASE( wxWindow* parent, wxWindowID id, const w
|
|||
m_e12 = new wxRadioButton( sbSizerESeriesInput->GetStaticBox(), wxID_ANY, _("E12"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bSizer40->Add( m_e12, 1, wxALL, 5 );
|
||||
|
||||
m_e24 = new wxRadioButton( sbSizerESeriesInput->GetStaticBox(), wxID_ANY, _("E24"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bSizer40->Add( m_e24, 0, wxALL, 5 );
|
||||
|
||||
|
||||
sbSizerESeriesInput->Add( bSizer40, 1, wxEXPAND, 5 );
|
||||
|
||||
|
@ -201,6 +204,7 @@ PANEL_E_SERIE_BASE::PANEL_E_SERIE_BASE( wxWindow* parent, wxWindowID id, const w
|
|||
m_e3->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( PANEL_E_SERIE_BASE::OnESeriesSelection ), NULL, this );
|
||||
m_e6->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( PANEL_E_SERIE_BASE::OnESeriesSelection ), NULL, this );
|
||||
m_e12->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( PANEL_E_SERIE_BASE::OnESeriesSelection ), NULL, this );
|
||||
m_e24->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( PANEL_E_SERIE_BASE::OnESeriesSelection ), NULL, this );
|
||||
m_buttonEScalculate->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_E_SERIE_BASE::OnCalculateESeries ), NULL, this );
|
||||
}
|
||||
|
||||
|
@ -211,6 +215,7 @@ PANEL_E_SERIE_BASE::~PANEL_E_SERIE_BASE()
|
|||
m_e3->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( PANEL_E_SERIE_BASE::OnESeriesSelection ), NULL, this );
|
||||
m_e6->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( PANEL_E_SERIE_BASE::OnESeriesSelection ), NULL, this );
|
||||
m_e12->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( PANEL_E_SERIE_BASE::OnESeriesSelection ), NULL, this );
|
||||
m_e24->Disconnect( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEventHandler( PANEL_E_SERIE_BASE::OnESeriesSelection ), NULL, this );
|
||||
m_buttonEScalculate->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_E_SERIE_BASE::OnCalculateESeries ), NULL, this );
|
||||
|
||||
}
|
||||
|
|
|
@ -981,6 +981,71 @@
|
|||
<event name="OnRadioButton">OnESeriesSelection</event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxRadioButton" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">E24</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_e24</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass">; ; forward_declare</property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="value">0</property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnRadioButton">OnESeriesSelection</event>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version 3.10.0-4761b0c5)
|
||||
// C++ code generated with wxFormBuilder (version 3.10.0-39-g3487c3cb)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
@ -55,6 +55,7 @@ class PANEL_E_SERIE_BASE : public CALCULATOR_PANEL
|
|||
wxRadioButton* m_e3;
|
||||
wxRadioButton* m_e6;
|
||||
wxRadioButton* m_e12;
|
||||
wxRadioButton* m_e24;
|
||||
wxStaticText* m_ESerieSimpleSolution;
|
||||
wxTextCtrl* m_ESeries_Sol2R;
|
||||
wxStaticText* m_ESeriesSimpleErr;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <algorithm>
|
||||
|
||||
#include <calculator_panels/panel_eserie.h>
|
||||
#include <wx/msgdlg.h>
|
||||
|
||||
/* If BENCHMARK is defined, any 4R E12 calculations will print its execution time to console
|
||||
* My Hasswell Enthusiast reports 225 mSec what are reproducible within plusminus 2 percent
|
||||
|
@ -30,7 +31,7 @@
|
|||
//#define BENCHMARK
|
||||
|
||||
#ifdef BENCHMARK
|
||||
#include <sys/time.h>
|
||||
#include <profile.h>
|
||||
#endif
|
||||
|
||||
#include "eserie.h"
|
||||
|
@ -39,6 +40,112 @@ extern double DoubleFromString( const wxString& TextValue );
|
|||
|
||||
E_SERIE r;
|
||||
|
||||
// Return a string from aValue (aValue is expected in ohms)
|
||||
// If aValue < 1000 the returned string is aValue with unit = R
|
||||
// If aValue >= 1000 the returned string is aValue/1000 with unit = K
|
||||
// with notation similar to 2K2
|
||||
// If aValue >= 1e6 the returned string is aValue/1e6 with unit = M
|
||||
// with notation = 1M
|
||||
static std::string strValue( double aValue )
|
||||
{
|
||||
std::string result;
|
||||
|
||||
if( aValue < 1000.0 )
|
||||
{
|
||||
result = std::to_string( static_cast<int>( aValue ) );
|
||||
result += 'R';
|
||||
}
|
||||
else
|
||||
{
|
||||
double div = 1e3;
|
||||
int unit = 'K';
|
||||
|
||||
if( aValue >= 1e6 )
|
||||
{
|
||||
div = 1e6;
|
||||
unit = 'M';
|
||||
}
|
||||
|
||||
aValue /= div;
|
||||
|
||||
int integer = static_cast<int>( aValue );
|
||||
result = std::to_string(integer);
|
||||
result += unit;
|
||||
|
||||
// Add mantissa: 1 digit, suitable for series up to E24
|
||||
double mantissa = aValue - integer;
|
||||
|
||||
if( mantissa > 0 )
|
||||
result += std::to_string( static_cast<int>( (mantissa*10)+0.5 ) );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
E_SERIE::E_SERIE()
|
||||
{
|
||||
// Build the list of available resistor values in each En serie
|
||||
double listValuesE1[] = { E1_VALUES };
|
||||
double listValuesE3[] = { E3_VALUES };
|
||||
double listValuesE6[] = { E6_VALUES };
|
||||
double listValuesE12[] = { E12_VALUES };
|
||||
double listValuesE24[] = { E24_VALUES };
|
||||
// buildSerieData must be called in the order of En series, because
|
||||
// the list of series is expected indexed by En for the serie En
|
||||
buildSerieData( E1, listValuesE1 );
|
||||
buildSerieData( E3, listValuesE3 );
|
||||
buildSerieData( E6, listValuesE6 );
|
||||
buildSerieData( E12, listValuesE12 );
|
||||
int count = buildSerieData( E24, listValuesE24 );
|
||||
|
||||
// Reserve a buffer for intermediate calculations:
|
||||
// the buffer size is 2*count*count to store all combinaisons of 2 values
|
||||
// there are 2*count*count = 29282 combinations for E24
|
||||
int bufsize = 2*count*count;
|
||||
m_cmb_lut.reserve( bufsize );
|
||||
|
||||
// Store predefined R_DATA items.
|
||||
for( int ii = 0; ii < bufsize; ii++ )
|
||||
m_cmb_lut.emplace_back( "", 0.0 );
|
||||
}
|
||||
|
||||
|
||||
int E_SERIE::buildSerieData( int aEserie, double aList[] )
|
||||
{
|
||||
double curr_coeff = FIRST_VALUE;
|
||||
int count = 0;
|
||||
|
||||
std::vector<R_DATA> curr_list;
|
||||
|
||||
for( ; ; )
|
||||
{
|
||||
double curr_r = curr_coeff;
|
||||
|
||||
for( int ii = 0; ; ii++ )
|
||||
{
|
||||
if( aList[ii] == 0.0 ) // End of list
|
||||
break;
|
||||
|
||||
double curr_r = curr_coeff * aList[ii];
|
||||
curr_list.emplace_back( strValue( curr_r ), curr_r );
|
||||
count++;
|
||||
|
||||
if( curr_r >= LAST_VALUE )
|
||||
break;
|
||||
}
|
||||
|
||||
if( curr_r >= LAST_VALUE )
|
||||
break;
|
||||
|
||||
curr_coeff *= 10;
|
||||
}
|
||||
|
||||
m_luts.push_back( std::move( curr_list ) );
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
void E_SERIE::Exclude( double aValue )
|
||||
{
|
||||
|
@ -46,7 +153,7 @@ void E_SERIE::Exclude( double aValue )
|
|||
{
|
||||
for( R_DATA& i : m_luts[m_series] ) // then search it in the selected E-Serie lookup table
|
||||
{
|
||||
if( i.e_value == aValue ) // if value to exclude found
|
||||
if( i.e_value == aValue ) // if the value to exclude is found
|
||||
i.e_use = false; // disable its use
|
||||
}
|
||||
}
|
||||
|
@ -57,15 +164,15 @@ void E_SERIE::simple_solution( uint32_t aSize )
|
|||
{
|
||||
uint32_t i;
|
||||
|
||||
m_results[S2R].e_value = std::numeric_limits<double>::max(); // assume no 2R solution or max deviation
|
||||
m_results.at( S2R ).e_value = std::numeric_limits<double>::max(); // assume no 2R solution or max deviation
|
||||
|
||||
for( i = 0; i < aSize; i++ )
|
||||
{
|
||||
if( abs( m_cmb_lut[i].e_value - m_required_value ) < abs( m_results[S2R].e_value ) )
|
||||
if( abs( m_cmb_lut.at( i ).e_value - m_required_value ) < abs( m_results.at( S2R ).e_value ) )
|
||||
{
|
||||
m_results[S2R].e_value = m_cmb_lut[i].e_value - m_required_value; // save signed deviation in Ohms
|
||||
m_results[S2R].e_name = m_cmb_lut[i].e_name; // save combination text
|
||||
m_results[S2R].e_use = true; // this is a possible solution
|
||||
m_results.at( S2R ).e_value = m_cmb_lut.at( i ).e_value - m_required_value; // save signed deviation in Ohms
|
||||
m_results.at( S2R ).e_name = m_cmb_lut.at( i ).e_name; // save combination text
|
||||
m_results.at( S2R ).e_use = true; // this is a possible solution
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -77,53 +184,53 @@ void E_SERIE::combine4( uint32_t aSize )
|
|||
double tmp;
|
||||
std::string s;
|
||||
|
||||
m_results[S4R].e_use = false; // disable 4R solution, until
|
||||
m_results[S4R].e_value = m_results[S3R].e_value; // 4R becomes better than 3R solution
|
||||
m_results.at( S4R ).e_use = false; // disable 4R solution, until
|
||||
m_results.at( S4R ).e_value = m_results.at( S3R ).e_value; // 4R becomes better than 3R solution
|
||||
|
||||
#ifdef BENCHMARK
|
||||
PROF_COUNTER combine4_timer; // start timer to count execution time
|
||||
PROF_COUNTER timer; // start timer to count execution time
|
||||
#endif
|
||||
|
||||
for( i = 0; i < aSize; i++ ) // 4R search outer loop
|
||||
{ // scan valid intermediate 2R solutions
|
||||
for( j = 0; j < aSize; j++ ) // inner loop combines all with itself
|
||||
{
|
||||
tmp = m_cmb_lut[i].e_value + m_cmb_lut[j].e_value; // calculate 2R+2R serial
|
||||
tmp = m_cmb_lut.at( i ).e_value + m_cmb_lut.at( j ).e_value; // calculate 2R+2R serial
|
||||
tmp -= m_required_value; // calculate 4R deviation
|
||||
|
||||
if( abs( tmp ) < abs( m_results[S4R].e_value ) ) // if new 4R is better
|
||||
if( abs( tmp ) < abs( m_results.at(S4R).e_value ) ) // if new 4R is better
|
||||
{
|
||||
m_results[S4R].e_value = tmp; // save amount of benefit
|
||||
m_results.at( S4R ).e_value = tmp; // save amount of benefit
|
||||
std::string s = "( ";
|
||||
s.append( m_cmb_lut[i].e_name ); // mention 1st 2 component
|
||||
s.append( m_cmb_lut.at( i ).e_name ); // mention 1st 2 component
|
||||
s.append( " ) + ( " ); // in series
|
||||
s.append( m_cmb_lut[j].e_name ); // with 2nd 2 components
|
||||
s.append( m_cmb_lut.at( j ).e_name ); // with 2nd 2 components
|
||||
s.append( " )" );
|
||||
m_results[S4R].e_name = s; // save the result and
|
||||
m_results[S4R].e_use = true; // enable for later use
|
||||
m_results.at( S4R ).e_name = s; // save the result and
|
||||
m_results.at( S4R ).e_use = true; // enable for later use
|
||||
}
|
||||
|
||||
tmp = ( m_cmb_lut[i].e_value * m_cmb_lut[j].e_value ) /
|
||||
( m_cmb_lut[i].e_value + m_cmb_lut[j].e_value ); // calculate 2R|2R parallel
|
||||
tmp = ( m_cmb_lut[i].e_value * m_cmb_lut.at( j ).e_value ) /
|
||||
( m_cmb_lut[i].e_value + m_cmb_lut.at( j ).e_value ); // calculate 2R|2R parallel
|
||||
tmp -= m_required_value; // calculate 4R deviation
|
||||
|
||||
if( abs( tmp ) < abs( m_results[S4R].e_value ) ) // if new 4R is better
|
||||
if( abs( tmp ) < abs( m_results.at( S4R ).e_value ) ) // if new 4R is better
|
||||
{
|
||||
m_results[S4R].e_value = tmp; // save amount of benefit
|
||||
m_results.at( S4R ).e_value = tmp; // save amount of benefit
|
||||
std::string s = "( ";
|
||||
s.append( m_cmb_lut[i].e_name ); // mention 1st 2 component
|
||||
s.append( m_cmb_lut.at( i ).e_name ); // mention 1st 2 component
|
||||
s.append( " ) | ( " ); // in parallel
|
||||
s.append( m_cmb_lut[j].e_name ); // with 2nd 2 components
|
||||
s.append( m_cmb_lut.at( j ).e_name ); // with 2nd 2 components
|
||||
s.append( " )" );
|
||||
m_results[S4R].e_name = s; // save the result
|
||||
m_results[S4R].e_use = true; // enable later use
|
||||
m_results.at( S4R ).e_name = s; // save the result
|
||||
m_results.at( S4R ).e_use = true; // enable later use
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BENCHMARK
|
||||
if( m_series == E12 )
|
||||
std::cout<<"4R Time = "<<combine4_timer.msecs()<<" mSec"<<std::endl;
|
||||
printf( "Calculation time = %d mS", timer.msecs() );
|
||||
fflush( 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -154,18 +261,17 @@ uint32_t E_SERIE::combine2()
|
|||
{
|
||||
if( j.e_use )
|
||||
{
|
||||
m_cmb_lut[combi2R].e_use = true;
|
||||
m_cmb_lut[combi2R].e_value = i.e_value + j.e_value; // calculate 2R serial
|
||||
m_cmb_lut.at( combi2R ).e_use = true;
|
||||
m_cmb_lut.at( combi2R ).e_value = i.e_value + j.e_value; // calculate 2R serial
|
||||
s = i.e_name;
|
||||
s.append( " + " );
|
||||
m_cmb_lut[combi2R].e_name = s.append( j.e_name);
|
||||
m_cmb_lut.at( combi2R ).e_name = s.append( j.e_name);
|
||||
combi2R++; // next destination
|
||||
m_cmb_lut[combi2R].e_use = true; // calculate 2R parallel
|
||||
m_cmb_lut[combi2R].e_value = i.e_value * j.e_value /
|
||||
( i.e_value + j.e_value );
|
||||
m_cmb_lut.at( combi2R ).e_use = true; // calculate 2R parallel
|
||||
m_cmb_lut.at( combi2R ).e_value = i.e_value * j.e_value / ( i.e_value + j.e_value );
|
||||
s = i.e_name;
|
||||
s.append( " | " );
|
||||
m_cmb_lut[combi2R].e_name = s.append( j.e_name );
|
||||
m_cmb_lut.at( combi2R ).e_name = s.append( j.e_name );
|
||||
combi2R++; // next destination
|
||||
}
|
||||
}
|
||||
|
@ -181,8 +287,8 @@ void E_SERIE::combine3( uint32_t aSize )
|
|||
double tmp = 0; // avoid warning for being uninitialized
|
||||
std::string s;
|
||||
|
||||
m_results[S3R].e_use = false; // disable 3R solution, until
|
||||
m_results[S3R].e_value = m_results[S2R].e_value; // 3R becomes better than 2R solution
|
||||
m_results.at( S3R ).e_use = false; // disable 3R solution, until
|
||||
m_results.at( S3R ).e_value = m_results.at( S2R ).e_value; // 3R becomes better than 2R solution
|
||||
|
||||
for( const R_DATA& i : m_luts[m_series] ) // 3R Outer loop to selected primary E serie LUT
|
||||
{
|
||||
|
@ -190,33 +296,33 @@ void E_SERIE::combine3( uint32_t aSize )
|
|||
{
|
||||
for( j = 0; j < aSize; j++ ) // inner loop combines with all 2R intermediate results
|
||||
{ // R+2R serial combi
|
||||
tmp = m_cmb_lut[j].e_value + i.e_value;
|
||||
tmp = m_cmb_lut.at( j ).e_value + i.e_value;
|
||||
tmp -= m_required_value; // calculate deviation
|
||||
|
||||
if( abs( tmp ) < abs( m_results[S3R].e_value ) ) // compare if better
|
||||
if( abs( tmp ) < abs( m_results.at( S3R ).e_value ) ) // compare if better
|
||||
{ // then take it
|
||||
s = i.e_name; // mention 3rd component
|
||||
s.append( " + ( " ); // in series
|
||||
s.append( m_cmb_lut[j].e_name ); // with 2R combination
|
||||
s.append( m_cmb_lut.at( j ).e_name ); // with 2R combination
|
||||
s.append( " )" );
|
||||
m_results[S3R].e_name = s; // save S3R result
|
||||
m_results[S3R].e_value = tmp; // save amount of benefit
|
||||
m_results[S3R].e_use = true; // enable later use
|
||||
m_results.at( S3R ).e_name = s; // save S3R result
|
||||
m_results.at( S3R ).e_value = tmp; // save amount of benefit
|
||||
m_results.at( S3R ).e_use = true; // enable later use
|
||||
}
|
||||
|
||||
tmp = i.e_value * m_cmb_lut[j].e_value /
|
||||
( i.e_value + m_cmb_lut[j].e_value ); // calculate R + 2R parallel
|
||||
tmp = i.e_value * m_cmb_lut.at( j ).e_value /
|
||||
( i.e_value + m_cmb_lut.at( j ).e_value ); // calculate R + 2R parallel
|
||||
tmp -= m_required_value; // calculate deviation
|
||||
|
||||
if( abs( tmp ) < abs( m_results[S3R].e_value ) ) // compare if better
|
||||
if( abs( tmp ) < abs( m_results.at( S3R ).e_value ) ) // compare if better
|
||||
{ // then take it
|
||||
s = i.e_name; // mention 3rd component
|
||||
s.append( " | ( " ); // in parallel
|
||||
s.append( m_cmb_lut[j].e_name ); // with 2R combination
|
||||
s.append( m_cmb_lut.at( j ).e_name ); // with 2R combination
|
||||
s.append( " )" );
|
||||
m_results[S3R].e_name = s;
|
||||
m_results[S3R].e_value = tmp; // save amount of benefit
|
||||
m_results[S3R].e_use = true; // enable later use
|
||||
m_results.at( S3R ).e_name = s;
|
||||
m_results.at( S3R ).e_value = tmp; // save amount of benefit
|
||||
m_results.at( S3R ).e_use = true; // enable later use
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -224,7 +330,7 @@ void E_SERIE::combine3( uint32_t aSize )
|
|||
|
||||
// If there is a 3R result with remaining deviation consider to search a possibly better 4R solution
|
||||
// calculate 4R for small series always
|
||||
if(( m_results[S3R].e_use == true ) && tmp )
|
||||
if(( m_results.at( S3R ).e_use == true ) && tmp )
|
||||
combine4( aSize );
|
||||
}
|
||||
|
||||
|
@ -236,7 +342,7 @@ void E_SERIE::Calculate()
|
|||
no_of_2Rcombi = combine2(); // combine all 2R combinations for selected E serie
|
||||
simple_solution( no_of_2Rcombi ); // search for simple 2 component solution
|
||||
|
||||
if( m_results[S2R].e_value ) // if simple 2R result is not exact
|
||||
if( m_results.at( S2R ).e_value ) // if simple 2R result is not exact
|
||||
combine3( no_of_2Rcombi ); // continiue searching for a possibly better solution
|
||||
|
||||
strip3();
|
||||
|
@ -248,16 +354,16 @@ void E_SERIE::strip3()
|
|||
{
|
||||
std::string s;
|
||||
|
||||
if( m_results[S3R].e_use ) // if there is a 3 term result available
|
||||
if( m_results.at( S3R ).e_use ) // if there is a 3 term result available
|
||||
{ // what is connected either by two "|" or by 3 plus
|
||||
s = m_results[S3R].e_name;
|
||||
s = m_results.at( S3R ).e_name;
|
||||
|
||||
if( ( std::count( s.begin(), s.end(), '+' ) == 2 )
|
||||
|| ( std::count( s.begin(), s.end(), '|' ) == 2 ) )
|
||||
{ // then strip one pair of braces
|
||||
s.erase( s.find( "(" ), 1 ); // it is known sure, this is available
|
||||
s.erase( s.find( ")" ), 1 ); // in any unstripped 3R result term
|
||||
m_results[S3R].e_name = s; // use stripped result
|
||||
m_results.at( S3R ).e_name = s; // use stripped result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -267,9 +373,9 @@ void E_SERIE::strip4()
|
|||
{
|
||||
std::string s;
|
||||
|
||||
if( m_results[S4R].e_use ) // if there is a 4 term result available
|
||||
if( m_results.at( S4R ).e_use ) // if there is a 4 term result available
|
||||
{ // what are connected either by 3 "+" or by 3 "|"
|
||||
s = m_results[S4R].e_name;
|
||||
s = m_results.at( S4R ).e_name;
|
||||
|
||||
if( ( std::count( s.begin(), s.end(), '+' ) == 3 )
|
||||
|| ( std::count( s.begin(), s.end(), '|' ) == 3 ) )
|
||||
|
@ -278,7 +384,7 @@ void E_SERIE::strip4()
|
|||
s.erase( s.find( ")" ), 1 ); // in any unstripped 4R result term
|
||||
s.erase( s.find( "(" ), 1 );
|
||||
s.erase( s.find( ")" ), 1 );
|
||||
m_results[S4R].e_name = s; // use stripped result
|
||||
m_results.at( S4R ).e_name = s; // use stripped result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -290,6 +396,8 @@ void PANEL_E_SERIE::OnCalculateESeries( wxCommandEvent& event )
|
|||
double error, err3 = 0;
|
||||
wxString es, fs; // error and formula strings
|
||||
|
||||
wxBusyCursor dummy;
|
||||
|
||||
reqr = ( 1000 * DoubleFromString( m_ResRequired->GetValue() ) );
|
||||
r.SetRequiredValue( reqr ); // keep a local copy of required resistor value
|
||||
r.NewCalc(); // assume all values available
|
||||
|
@ -302,7 +410,19 @@ void PANEL_E_SERIE::OnCalculateESeries( wxCommandEvent& event )
|
|||
r.Exclude( 1000 * DoubleFromString( m_ResRequired->GetValue()));
|
||||
r.Exclude( 1000 * DoubleFromString( m_ResExclude1->GetValue()));
|
||||
r.Exclude( 1000 * DoubleFromString( m_ResExclude2->GetValue()));
|
||||
|
||||
try
|
||||
{
|
||||
r.Calculate();
|
||||
}
|
||||
catch (std::out_of_range const& exc)
|
||||
{
|
||||
wxString msg;
|
||||
msg << "Internal error: " << exc.what();
|
||||
|
||||
wxMessageBox( msg );
|
||||
return;
|
||||
}
|
||||
|
||||
fs = r.GetResults()[S2R].e_name; // show 2R solution formula string
|
||||
m_ESeries_Sol2R->SetValue( fs );
|
||||
|
@ -386,6 +506,8 @@ void PANEL_E_SERIE::OnESeriesSelection( wxCommandEvent& event )
|
|||
r.SetSeries( E3 );
|
||||
else if( event.GetEventObject() == m_e12 )
|
||||
r.SetSeries( E12 );
|
||||
else if( event.GetEventObject() == m_e24 )
|
||||
r.SetSeries( E24 );
|
||||
else
|
||||
r.SetSeries( E6 );
|
||||
}
|
||||
|
|
|
@ -31,86 +31,55 @@
|
|||
* also used to lookup non calculable but readable BOM value strings. Supported E-series are:
|
||||
*/
|
||||
|
||||
enum { E1, E3, E6, E12 };
|
||||
// List of normalized values between 1 and 10
|
||||
// The terminal 0.0 value is a end of list value
|
||||
// Note also due to calculation time the E24 serie is the biggest usable.
|
||||
#define E24_VALUES 1.0, 1.1, 1.2, 1.3, 1.5, 1.6, 1.8, 2.0, 2.2, 2.4, 2.7, 3.0,\
|
||||
3.3, 3.6, 3.9, 4.3, 4.7, 5.1, 5.6, 6.2, 6.8, 7.5, 8.2, 9.1, 0.0
|
||||
|
||||
#define E12_VALUES 1.0, 1.2, 1.5, 1.8, 2.2, 2.7, 3.3, 3.9, 4.7, 5.6, 6.8, 8.2, 0.0
|
||||
|
||||
#define E6_VALUES 1.0, 1.5, 2.2, 3.3, 4.7, 6.8, 0.0
|
||||
|
||||
#define E3_VALUES 1.0, 2.2, 4.7, 0.0
|
||||
|
||||
#define E1_VALUES 1.0, 0.0
|
||||
|
||||
|
||||
// First value of resistor in ohm
|
||||
#define FIRST_VALUE 10
|
||||
|
||||
// last value of resistor in ohm
|
||||
#define LAST_VALUE 1e6
|
||||
|
||||
/**
|
||||
* List of handled E series values:
|
||||
* Note: series bigger than E24 have no interest because
|
||||
* - probably the user will fing the needed value inside these series
|
||||
* - the calcuation time can be *very high* for series > E24
|
||||
*/
|
||||
enum { E1, E3, E6, E12, E24 };
|
||||
|
||||
/**
|
||||
* This calculator suggests solutions for 2R, 3R and 4R replacement combinations
|
||||
*/
|
||||
|
||||
enum { S2R, S3R, S4R };
|
||||
|
||||
/**
|
||||
* 6 decade E-series values from 10 Ohms to 1M and its associated BOM strings.
|
||||
* Series E3,E6,E12 are defined by additional values for cumulative use with previous series
|
||||
*/
|
||||
|
||||
#define E1_VAL { true, "1K", 1000 },\
|
||||
{ true, "10K", 10000 },\
|
||||
{ true, "100K", 100000 },\
|
||||
{ true, "10R", 10 },\
|
||||
{ true, "100R", 100 },\
|
||||
{ true, "1M", 1000000 }
|
||||
|
||||
#define E3_ADD { true, "22R", 22 },\
|
||||
{ true, "47R", 47 },\
|
||||
{ true, "220R", 220 },\
|
||||
{ true, "470R", 470 },\
|
||||
{ true, "2K2", 2200 },\
|
||||
{ true, "4K7", 4700 },\
|
||||
{ true, "22K", 22000 },\
|
||||
{ true, "47K", 47000 },\
|
||||
{ true, "220K", 220000 },\
|
||||
{ true, "470K", 470000 }
|
||||
|
||||
#define E6_ADD { true, "15R", 15 },\
|
||||
{ true, "33R", 33 },\
|
||||
{ true, "68R", 68 },\
|
||||
{ true, "150R", 150 },\
|
||||
{ true, "330R", 330 },\
|
||||
{ true, "680R", 680 },\
|
||||
{ true, "1K5", 1500 },\
|
||||
{ true, "3K3", 3300 },\
|
||||
{ true, "6K8", 6800 },\
|
||||
{ true, "15K", 15000 },\
|
||||
{ true, "33K", 33000 },\
|
||||
{ true, "68K", 68000 },\
|
||||
{ true, "150K", 150000 },\
|
||||
{ true, "330K", 330000 },\
|
||||
{ true, "680K", 680000 }
|
||||
|
||||
#define E12_ADD { true, "12R", 12 },\
|
||||
{ true, "18R", 18 },\
|
||||
{ true, "27R", 27 },\
|
||||
{ true, "39R", 39 },\
|
||||
{ true, "56R", 56 },\
|
||||
{ true, "82R", 82 },\
|
||||
{ true, "120R", 120 },\
|
||||
{ true, "180R", 180 },\
|
||||
{ true, "270R", 270 },\
|
||||
{ true, "390R", 390 },\
|
||||
{ true, "560R", 560 },\
|
||||
{ true, "820R", 820 },\
|
||||
{ true, "1K2", 1200 },\
|
||||
{ true, "1K8", 1800 },\
|
||||
{ true, "2K7", 2700 },\
|
||||
{ true, "3K9", 3900 },\
|
||||
{ true, "5K6", 5600 },\
|
||||
{ true, "8K2", 8200 },\
|
||||
{ true, "12K", 12000 },\
|
||||
{ true, "18K", 18000 },\
|
||||
{ true, "27K", 27000 },\
|
||||
{ true, "39K", 39000 },\
|
||||
{ true, "56K", 56000 },\
|
||||
{ true, "82K", 82000 },\
|
||||
{ true, "120K", 120000 },\
|
||||
{ true, "180K", 180000 },\
|
||||
{ true, "270K", 270000 },\
|
||||
{ true, "390K", 390000 },\
|
||||
{ true, "560K", 560000 },\
|
||||
{ true, "820K", 820000 }
|
||||
|
||||
// R_DATA handles a resitor: string value, value and allowed to use
|
||||
struct R_DATA
|
||||
{
|
||||
R_DATA() :
|
||||
e_use( true ),
|
||||
e_value( 0.0 )
|
||||
{}
|
||||
|
||||
R_DATA( const std::string& aName, double aValue )
|
||||
{
|
||||
e_use = true;
|
||||
e_name = aName;
|
||||
e_value = aValue;
|
||||
}
|
||||
|
||||
bool e_use;
|
||||
std::string e_name;
|
||||
double e_value;
|
||||
|
@ -119,6 +88,8 @@ struct R_DATA
|
|||
class E_SERIE
|
||||
{
|
||||
public:
|
||||
E_SERIE();
|
||||
|
||||
/**
|
||||
* If any value of the selected E-serie not available, it can be entered as an exclude value.
|
||||
*
|
||||
|
@ -143,9 +114,18 @@ public:
|
|||
void SetSeries( uint32_t aSeries ) { m_series = aSeries; }
|
||||
void SetRequiredValue( double aValue ) { m_required_value = aValue; }
|
||||
|
||||
std::array<R_DATA,S4R+1> GetResults() { return m_results; }
|
||||
// Accessor:
|
||||
const std::array<R_DATA,S4R+1>& GetResults() { return m_results; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* Build the list of R_DATA existing for a given serie
|
||||
* Series are E1, E6 ..
|
||||
* The values are extracted from the E96_VALUES list
|
||||
* @return the count of items added in list
|
||||
*/
|
||||
int buildSerieData( int aEserie, double aList[] );
|
||||
|
||||
/**
|
||||
* Build all 2R combinations from the selected E-serie values
|
||||
*
|
||||
|
@ -200,32 +180,20 @@ private:
|
|||
void strip4();
|
||||
|
||||
private:
|
||||
std::vector<std::vector<R_DATA>> m_luts
|
||||
{
|
||||
{ E1_VAL },
|
||||
{ E1_VAL, E3_ADD },
|
||||
{ E1_VAL, E3_ADD, E6_ADD },
|
||||
{ E1_VAL, E3_ADD, E6_ADD, E12_ADD }
|
||||
};
|
||||
std::vector<std::vector<R_DATA>> m_luts;
|
||||
|
||||
/*
|
||||
* TODO: Manual array size calculation is dangerous. Unlike legacy ANSI-C Arrays
|
||||
* std::array can not drop length param by providing aggregate init list up
|
||||
* to C++17. Reserved array size should be 2*E12² of std::vector primary list.
|
||||
* Exceeding memory limit 7442 will crash the calculator without any warnings !
|
||||
* Compare to previous MAX_COMB macro for legacy ANSI-C array automatic solution
|
||||
* #define E12_SIZE sizeof ( e12_lut ) / sizeof ( R_DATA )
|
||||
* #define MAX_COMB (2 * E12_SIZE * E12_SIZE)
|
||||
/* Note: intermediate calculations use m_cmb_lut
|
||||
* if the biggest list is En, reserved array size should be 2*En*En of std::vector primary list.
|
||||
* 2 component combinations including redundant swappable terms are for the moment
|
||||
* ( using values between 10 ohms and 1Mohm )
|
||||
* 72 combinations for E1
|
||||
* 512 combinations for E3
|
||||
* 1922 combinations for E6
|
||||
* 7442 combinations for E12
|
||||
* 29282 combinations for E24
|
||||
*/
|
||||
std::vector<R_DATA> m_cmb_lut; // intermediate 2R combinations
|
||||
|
||||
#define MAX_CMB 7442 // maximum combinations for E12
|
||||
|
||||
std::array<R_DATA, MAX_CMB> m_cmb_lut; // intermediate 2R combinations
|
||||
std::array<R_DATA, S4R+1> m_results; // 2R, 3R and 4R results
|
||||
uint32_t m_series = E6; // Radio Button State
|
||||
uint32_t m_enable_4R = false; // Check Box 4R enable
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
// Do not edit this file, it is autogenerated by CMake from the .md file
|
||||
_HKI( "E-series defined in IEC 60063 are a widely accepted system of preferred\n"
|
||||
"numbers for electronic components. Available values are approximately\n"
|
||||
"equally spaced in a logarithmic scale.\n"
|
||||
_HKI( "E-series are defined in IEC 60063.\n"
|
||||
"\n"
|
||||
" E12: 1.0 1.2 1.5 1.8 2.2 2.7 3.3 3.9 4.7 5.6 6.8 8.2\n"
|
||||
" E6: 1.0 - 1.5 - 2.2 - 3.3 - 4.7 - 6.8 -\n"
|
||||
" E3: 1.0 - - - 2.2 - - - 4.7 - - -\n"
|
||||
"Available values are approximately equally spaced in a logarithmic scale.\n"
|
||||
"\n"
|
||||
" E24(5%): 1.0 1.1 1.2 1.3 1.5 1.6 1.8 2.0 2.2 2.4 2.7 3.0 3.3 3.6 3.9 4.3 4.7 5.1 5.6 6.2 6.8 7.5 8.2 9.1\n"
|
||||
" E12(10%): 1.0 1.2 1.5 1.8 2.2 2.7 3.3 3.9 4.7 5.6 6.8 8.2\n"
|
||||
" E6(20%): 1.0 - 1.5 - 2.2 - 3.3 - 4.7 - 6.8 -\n"
|
||||
" E3(50%): 1.0 - - - 2.2 - - - 4.7 - - -\n"
|
||||
" E1 : 1.0 - - - - - - - - - - -\n"
|
||||
"\n"
|
||||
"This calculator finds combinations of standard E-series components to\n"
|
||||
"create arbitrary values. You can enter the required resistance from 0.0025 to 4000 kΩ.\n"
|
||||
"Solutions using up to 4 components are given.\n"
|
||||
"- This calculator finds combinations of standard E-series (between 10Ω and 1MΩ) to create arbitrary values.\n"
|
||||
"- You can enter the required resistance from 0.0025 to 4000 kΩ.\n"
|
||||
"- Solutions using up to 4 components are given.\n"
|
||||
"\n"
|
||||
"By default, the request value is always excluded from the solution set. It is also possible to specify\n"
|
||||
"up to two additional values to exclude from the solution if these component values are not available\n"
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
E-series defined in IEC 60063 are a widely accepted system of preferred
|
||||
numbers for electronic components. Available values are approximately
|
||||
equally spaced in a logarithmic scale.
|
||||
E-series are defined in IEC 60063.
|
||||
|
||||
E12: 1.0 1.2 1.5 1.8 2.2 2.7 3.3 3.9 4.7 5.6 6.8 8.2
|
||||
E6: 1.0 - 1.5 - 2.2 - 3.3 - 4.7 - 6.8 -
|
||||
E3: 1.0 - - - 2.2 - - - 4.7 - - -
|
||||
Available values are approximately equally spaced in a logarithmic scale.
|
||||
|
||||
E24(5%): 1.0 1.1 1.2 1.3 1.5 1.6 1.8 2.0 2.2 2.4 2.7 3.0 3.3 3.6 3.9 4.3 4.7 5.1 5.6 6.2 6.8 7.5 8.2 9.1
|
||||
E12(10%): 1.0 1.2 1.5 1.8 2.2 2.7 3.3 3.9 4.7 5.6 6.8 8.2
|
||||
E6(20%): 1.0 - 1.5 - 2.2 - 3.3 - 4.7 - 6.8 -
|
||||
E3(50%): 1.0 - - - 2.2 - - - 4.7 - - -
|
||||
E1 : 1.0 - - - - - - - - - - -
|
||||
|
||||
This calculator finds combinations of standard E-series components to
|
||||
create arbitrary values. You can enter the required resistance from 0.0025 to 4000 kΩ.
|
||||
Solutions using up to 4 components are given.
|
||||
- This calculator finds combinations of standard E-series (between 10Ω and 1MΩ) to create arbitrary values.
|
||||
- You can enter the required resistance from 0.0025 to 4000 kΩ.
|
||||
- Solutions using up to 4 components are given.
|
||||
|
||||
By default, the request value is always excluded from the solution set. It is also possible to specify
|
||||
up to two additional values to exclude from the solution if these component values are not available
|
||||
|
|
Loading…
Reference in New Issue