KiCad PCB EDA Suite
panel_regulator.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) 1992-2011 jean-pierre.charras
5 * Copyright (C) 1992-2021 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
22//#include <macros.h>
23
24#include <wx/choicdlg.h>
25#include <wx/filedlg.h>
26#include <wx/msgdlg.h>
27
28#include <bitmaps.h>
33
34extern double DoubleFromString( const wxString& TextValue );
35
36// extension of pcb_calculator data filename:
37static const wxString DataFileNameExt( wxT( "pcbcalc" ) );
38
39
40PANEL_REGULATOR::PANEL_REGULATOR( wxWindow* parent, wxWindowID id,
41 const wxPoint& pos, const wxSize& size,
42 long style, const wxString& name ) :
43 PANEL_REGULATOR_BASE( parent, id, pos, size, style, name ),
44 m_RegulatorListChanged( false )
45{
46 m_IadjUnitLabel->SetLabel( wxT( "µA" ) );
47 m_r1Units->SetLabel( wxT( "kΩ" ) );
48 m_r2Units->SetLabel( wxT( "kΩ" ) );
49
52
55
56 // Needed on wxWidgets 3.0 to ensure sizers are correctly set
57 GetSizer()->SetSizeHints( this );
58}
59
61{
62}
63
64
66{
67 // Update the bitmaps
70}
71
72
74{
76}
77
78
80{
81 m_RegulR1Value->SetValue( wxT( "10" ) );
82 m_RegulR2Value->SetValue( wxT( "10" ) );
83 m_RegulVrefValue->SetValue( wxT( "3" ) );
84 m_RegulVoutValue->SetValue( wxT( "12" ) );
85 m_choiceRegType->SetSelection( 0 );
86 m_rbRegulR1->SetValue( true );
87 m_rbRegulR2->SetValue( false );
88 m_rbRegulVout->SetValue( false );
90}
91
92
94{
95 switch( m_choiceRegType->GetSelection() )
96 {
97 default:
98 case 0:
99 m_bitmapRegul4pins->Show( true );
100 m_bitmapRegul3pins->Show( false );
101 m_RegulIadjValue->Enable( false );
102 m_RegulFormula->SetLabel( wxT( "Vout = Vref * (R1 + R2) / R2" ) );
103 break;
104
105 case 1:
106 m_bitmapRegul4pins->Show( false );
107 m_bitmapRegul3pins->Show( true );
108 m_RegulIadjValue->Enable( true );
109 m_RegulFormula->SetLabel( wxT( "Vout = Vref * (R1 + R2) / R1 + Iadj * R2" ) );
110 break;
111 }
112
113 // The new icon size must be taken in account
114 GetSizer()->Layout();
115
116 // Enable/disable buttons:
117 bool enbl = m_choiceRegulatorSelector->GetCount() > 0;
118 m_buttonEditItem->Enable( enbl );
119 m_buttonRemoveItem->Enable( enbl );
120
121 Refresh();
122}
123
124
125void PANEL_REGULATOR::OnRegulTypeSelection( wxCommandEvent& event )
126{
128}
129
130
131void PANEL_REGULATOR::OnRegulatorSelection( wxCommandEvent& event )
132{
133 wxString name = m_choiceRegulatorSelector->GetStringSelection();
135
136 if( item )
137 {
139 m_choiceRegType->SetSelection( item->m_Type );
140 wxString value;
141 value.Printf( wxT( "%g" ), item->m_Vref );
142 m_RegulVrefValue->SetValue( value );
143 value.Printf( wxT( "%g" ), item->m_Iadj );
144 m_RegulIadjValue->SetValue( value );
145 }
146
147 // Call RegulatorPageUpdate to enable/disable tools,
148 // even if no item selected
150}
151
152
153void PANEL_REGULATOR::OnDataFileSelection( wxCommandEvent& event )
154{
155 wxString fullfilename = GetDataFilename();
156
157 wxString wildcard;
158 wildcard.Printf( _("PCB Calculator data file" ) + wxT( " (*.%s)|*.%s"),
160
161 wxFileDialog dlg( this, _("Select PCB Calculator Data File"),
162 wxEmptyString, fullfilename, wildcard, wxFD_OPEN );
163
164 if( dlg.ShowModal() == wxID_CANCEL )
165 return;
166
167 fullfilename = dlg.GetPath();
168
169 if( fullfilename == GetDataFilename() )
170 return;
171
172 SetDataFilename( fullfilename );
173
174 if( wxFileExists( fullfilename ) && m_RegulatorList.GetCount() > 0 ) // Read file
175 {
176 if( wxMessageBox( _( "Do you want to load this file and replace current regulator list?" ) )
177 != wxID_OK )
178 {
179 return;
180 }
181 }
182
183 if( ReadDataFile() )
184 {
189 }
190 else
191 {
192 wxString msg;
193 msg.Printf( _("Unable to read data file '%s'."), fullfilename );
194 wxMessageBox( msg );
195 }
196}
197
198
199void PANEL_REGULATOR::OnAddRegulator( wxCommandEvent& event )
200{
201 DIALOG_REGULATOR_FORM dlg( this, wxEmptyString );
202
203 if( dlg.ShowModal() != wxID_OK )
204 return;
205
206 REGULATOR_DATA* new_item = dlg.BuildRegulatorFromData();
207
208 // Add new item, if not existing
209 if( m_RegulatorList.GetReg( new_item->m_Name ) == nullptr )
210 {
211 // Add item in list
212 m_RegulatorList.Add( new_item );
218 }
219 else
220 {
221 wxMessageBox( _("This regulator is already in list. Aborted") );
222 delete new_item;
223 }
224}
225
226
227void PANEL_REGULATOR::OnEditRegulator( wxCommandEvent& event )
228{
229 wxString name = m_choiceRegulatorSelector->GetStringSelection();
231
232 if( item == nullptr )
233 return;
234
235 DIALOG_REGULATOR_FORM dlg( this, name );
236
237 dlg.CopyRegulatorDataToDialog( item );
238
239 if( dlg.ShowModal() != wxID_OK )
240 return;
241
242 REGULATOR_DATA* new_item = dlg.BuildRegulatorFromData();
243 m_RegulatorList.Replace( new_item );
244
246
248}
249
250
251void PANEL_REGULATOR::OnRemoveRegulator( wxCommandEvent& event )
252{
253 wxString name = wxGetSingleChoice( _("Remove Regulator"), wxEmptyString,
255 if( name.IsEmpty() )
256 return;
257
262
265
267}
268
269
271{
272 // Find last selected in regulator list:
273 int idx = -1;
274
275 if( !m_lastSelectedRegulatorName.IsEmpty() )
276 {
277 for( unsigned ii = 0; ii < m_RegulatorList.GetCount(); ii++ )
278 {
280 {
281 idx = ii;
282 break;
283 }
284 }
285 }
286
287 m_choiceRegulatorSelector->SetSelection( idx );
288 wxCommandEvent event;
289 OnRegulatorSelection( event );
290}
291
292
294{
295 int id;
296
297 if( m_rbRegulR1->GetValue() )
298 {
299 id = 0; // for R1 calculation
300 }
301 else if( m_rbRegulR2->GetValue() )
302 {
303 id = 1; // for R2 calculation
304 }
305 else if( m_rbRegulVout->GetValue() )
306 {
307 id = 2; // for Vout calculation
308 }
309 else
310 {
311 wxMessageBox( wxT("Selection error" ) );
312 return;
313 }
314
315 double r1, r2, vref, vout;
316
317 wxString txt;
318
319 m_RegulMessage->SetLabel( wxEmptyString);
320
321 // Convert r1 and r2 in ohms
322 int r1scale = 1000;
323 int r2scale = 1000;
324
325 // Read values from panel:
326 txt = m_RegulR1Value->GetValue();
327 r1 = DoubleFromString( txt ) * r1scale;
328 txt = m_RegulR2Value->GetValue();
329 r2 = DoubleFromString( txt ) * r2scale;
330 txt = m_RegulVrefValue->GetValue();
331 vref = DoubleFromString( txt );
332 txt = m_RegulVoutValue->GetValue();
333 vout = DoubleFromString( txt );
334
335 // Some tests:
336 if( vout < vref && id != 2 )
337 {
338 m_RegulMessage->SetLabel( _("Vout must be greater than vref" ) );
339 return;
340 }
341
342 if( vref == 0.0 )
343 {
344 m_RegulMessage->SetLabel( _( "Vref set to 0 !" ) );
345 return;
346 }
347
348 if( ( r1 < 0 && id != 0 ) || ( r2 <= 0 && id != 1 ) )
349 {
350 m_RegulMessage->SetLabel( _("Incorrect value for R1 R2" ) );
351 return;
352 }
353
354 // Calculate
355 if( m_choiceRegType->GetSelection() == 1)
356 {
357 // 3 terminal regulator
358 txt = m_RegulIadjValue->GetValue();
359 double iadj = DoubleFromString( txt );
360
361 // iadj is given in micro amp, so convert it in amp.
362 iadj /= 1000000;
363
364 switch( id )
365 {
366 case 0:
367 r1 = vref * r2 / ( vout - vref - ( r2 * iadj ) );
368 break;
369
370 case 1:
371 r2 = ( vout - vref ) / ( iadj + ( vref / r1 ) );
372 break;
373
374 case 2:
375 vout = vref * ( r1 + r2 ) / r1;
376 vout += r2 * iadj;
377 break;
378 }
379 }
380 else
381 { // Standard 4 terminal regulator
382 switch( id )
383 {
384 case 0: r1 = ( vout / vref - 1 ) * r2; break;
385 case 1: r2 = r1 / ( vout / vref - 1 ); break;
386 case 2: vout = vref * ( r1 + r2 ) / r2; break;
387 }
388 }
389
390 // write values to panel:
391 txt.Printf( wxT( "%g" ), r1 / r1scale );
392 m_RegulR1Value->SetValue( txt );
393 txt.Printf( wxT( "%g" ), r2 / r2scale );
394 m_RegulR2Value->SetValue( txt );
395 txt.Printf( wxT( "%g" ), vref );
396 m_RegulVrefValue->SetValue( txt );
397 txt.Printf( wxT( "%g" ), vout );
398 m_RegulVoutValue->SetValue( txt );
399}
400
401
403{
404 // Save current parameter values in config.
405 aCfg->m_Regulators.r1 = m_RegulR1Value->GetValue();
406 aCfg->m_Regulators.r2 = m_RegulR2Value->GetValue();
407 aCfg->m_Regulators.vref = m_RegulVrefValue->GetValue();
408 aCfg->m_Regulators.vout = m_RegulVoutValue->GetValue();
411 aCfg->m_Regulators.type = m_choiceRegType->GetSelection();
412
413 // Store the parameter selection that was recently calculated (R1, R2 or Vout)
414 wxRadioButton* regprms[3] = { m_rbRegulR1, m_rbRegulR2, m_rbRegulVout };
415
416 for( int ii = 0; ii < 3; ii++ )
417 {
418 if( regprms[ii]->GetValue() )
419 {
420 aCfg->m_Regulators.last_param = ii;
421 break;
422 }
423 }
424}
425
426
428{
429 m_RegulR1Value->SetValue( aCfg->m_Regulators.r1 );
430 m_RegulR2Value->SetValue( aCfg->m_Regulators.r2 );
431 m_RegulVrefValue->SetValue( aCfg->m_Regulators.vref );
432 m_RegulVoutValue->SetValue( aCfg->m_Regulators.vout );
435 m_choiceRegType->SetSelection( aCfg->m_Regulators.type );
436
437 wxRadioButton* regprms[3] = { m_rbRegulR1, m_rbRegulR2, m_rbRegulVout };
438
439 if( aCfg->m_Regulators.last_param >= 3 )
440 aCfg->m_Regulators.last_param = 0;
441
442 for( int ii = 0; ii < 3; ii++ )
443 regprms[ii]->SetValue( aCfg->m_Regulators.last_param == ii );
444
445}
446
447
449{
450 // TODO: This was empty for some reason, should we actually save settings here?
451}
452
453
455{
456 if( m_regulators_fileNameCtrl->GetValue().IsEmpty() )
457 return wxEmptyString;
458
459 wxFileName fn( m_regulators_fileNameCtrl->GetValue() );
460 fn.SetExt( DataFileNameExt );
461 return fn.GetFullPath();
462}
463
464
465void PANEL_REGULATOR::SetDataFilename( const wxString& aFilename )
466{
467 if( aFilename.IsEmpty() )
468 {
469 m_regulators_fileNameCtrl->SetValue( wxEmptyString );
470 }
471 else
472 {
473 wxFileName fn( aFilename );
474 fn.SetExt( DataFileNameExt );
475 m_regulators_fileNameCtrl->SetValue( fn.GetFullPath() );
476 }
477}
const char * name
Definition: DXF_plotter.cpp:56
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:105
Subclass of DIALOG_REGULATOR_FORM_BASE, which is generated by wxFormBuilder.
REGULATOR_DATA * BuildRegulatorFromData()
Create a new REGULATOR_DATA from dialog data.
void CopyRegulatorDataToDialog(REGULATOR_DATA *aItem)
Transfer data from dialog to aItem.
Class PANEL_REGULATOR_BASE.
wxStaticText * m_RegulFormula
wxStaticText * m_RegulMessage
wxStaticText * m_IadjUnitLabel
wxTextCtrl * m_regulators_fileNameCtrl
wxRadioButton * m_rbRegulVout
wxStaticBitmap * m_bitmapRegul4pins
wxChoice * m_choiceRegulatorSelector
wxStaticBitmap * m_bitmapRegul3pins
wxRadioButton * m_rbRegulR2
wxRadioButton * m_rbRegulR1
void OnEditRegulator(wxCommandEvent &event) override
void OnRegulatorSelection(wxCommandEvent &event) override
void OnRegulatorResetButtonClick(wxCommandEvent &event) override
REGULATOR_LIST m_RegulatorList
void ThemeChanged() override
Update UI elements of the panel when the theme changes to ensure the images and fonts/colors are appr...
void Regulators_WriteConfig(PCB_CALCULATOR_SETTINGS *aCfg)
Write regulators parameters in configuration.
const wxString GetDataFilename()
void OnRegulatorCalcButtonClick(wxCommandEvent &event) override
void OnDataFileSelection(wxCommandEvent &event) override
void SetDataFilename(const wxString &aFilename)
Initialize the full filename of the selected pcb_calculator data file force the standard extension of...
void SelectLastSelectedRegulator()
If m_lastSelectedRegulatorName is empty, just calls RegulatorPageUpdate()
void OnRegulTypeSelection(wxCommandEvent &event) override
void SaveSettings(PCB_CALCULATOR_SETTINGS *aCfg) override
Save the settings from the panel.
void OnRemoveRegulator(wxCommandEvent &event) override
wxString m_lastSelectedRegulatorName
void OnAddRegulator(wxCommandEvent &event) override
PANEL_REGULATOR(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL, const wxString &name=wxEmptyString)
void LoadSettings(PCB_CALCULATOR_SETTINGS *aCfg) override
Load the settings into the panel.
void RegulatorPageUpdate()
Update the regulator page dialog display.
void Remove(const wxString &aRegName)
wxArrayString GetRegList() const
void Replace(REGULATOR_DATA *aItem)
Replace an old REGULATOR_DATA by a new one The old one is deleted the 2 items must have the same name...
void Add(REGULATOR_DATA *aItem)
REGULATOR_DATA * GetReg(const wxString &aName)
unsigned int GetCount()
std::vector< REGULATOR_DATA * > m_List
Contains structures for storage of regulator data.
#define _(s)
static const wxString DataFileNameExt(wxT("pcbcalc"))
double DoubleFromString(const wxString &TextValue)
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...