KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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-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#include <wx/choicdlg.h>
22#include <wx/filedlg.h>
23#include <wx/msgdlg.h>
24
25#include <bitmaps.h>
30
31extern double DoubleFromString( const wxString& TextValue );
32
33// extension of pcb_calculator data filename:
34static const wxString DataFileNameExt( wxT( "pcbcalc" ) );
35
36
37PANEL_REGULATOR::PANEL_REGULATOR( wxWindow* parent, wxWindowID id, const wxPoint& pos,
38 const wxSize& size, long style, const wxString& name ) :
39 PANEL_REGULATOR_BASE( parent, id, pos, size, style, name ),
40 m_RegulatorListChanged( false )
41{
42 m_IadjUnitLabel->SetLabel( wxT( "µA" ) );
43 m_r1Units->SetLabel( wxT( "kΩ" ) );
44 m_r2Units->SetLabel( wxT( "kΩ" ) );
45
46 m_bitmapRegul3pins->SetBitmap( KiBitmap( BITMAPS::regul_3pins ) );
47 m_bitmapRegul4pins->SetBitmap( KiBitmap( BITMAPS::regul ) );
48
51
52 // Needed on wxWidgets 3.0 to ensure sizers are correctly set
53 GetSizer()->SetSizeHints( this );
54}
55
57{
58}
59
60
62{
63 // Update the bitmaps
64 m_bitmapRegul3pins->SetBitmap( KiBitmap( BITMAPS::regul_3pins ) );
65 m_bitmapRegul4pins->SetBitmap( KiBitmap( BITMAPS::regul ) );
66}
67
68
70{
72}
73
74
76{
77 m_RegulR1Value->SetValue( wxT( "10" ) );
78 m_RegulR2Value->SetValue( wxT( "10" ) );
79 m_RegulVrefValue->SetValue( wxT( "3" ) );
80 m_RegulVoutValue->SetValue( wxT( "12" ) );
81 m_choiceRegType->SetSelection( 0 );
82 m_rbRegulR1->SetValue( true );
83 m_rbRegulR2->SetValue( false );
84 m_rbRegulVout->SetValue( false );
86}
87
88
90{
91 switch( m_choiceRegType->GetSelection() )
92 {
93 default:
94 case 0:
95 m_bitmapRegul4pins->Show( true );
96 m_bitmapRegul3pins->Show( false );
97 m_RegulIadjValue->Enable( false );
98 m_RegulFormula->SetLabel( wxT( "Vout = Vref * (R1 + R2) / R2" ) );
99 break;
100
101 case 1:
102 m_bitmapRegul4pins->Show( false );
103 m_bitmapRegul3pins->Show( true );
104 m_RegulIadjValue->Enable( true );
105 m_RegulFormula->SetLabel( wxT( "Vout = Vref * (R1 + R2) / R1 + Iadj * R2" ) );
106 break;
107 }
108
109 // The new icon size must be taken in account
110 GetSizer()->Layout();
111
112 // Enable/disable buttons:
113 bool enbl = m_choiceRegulatorSelector->GetCount() > 0;
114 m_buttonEditItem->Enable( enbl );
115 m_buttonRemoveItem->Enable( enbl );
116
117 Refresh();
118}
119
120
121void PANEL_REGULATOR::OnRegulTypeSelection( wxCommandEvent& event )
122{
124}
125
126
127void PANEL_REGULATOR::OnRegulatorSelection( wxCommandEvent& event )
128{
129 wxString name = m_choiceRegulatorSelector->GetStringSelection();
131
132 if( item )
133 {
135 m_choiceRegType->SetSelection( item->m_Type );
136 wxString value;
137 value.Printf( wxT( "%g" ), item->m_Vref );
138 m_RegulVrefValue->SetValue( value );
139 value.Printf( wxT( "%g" ), item->m_Iadj );
140 m_RegulIadjValue->SetValue( value );
141 }
142
143 // Call RegulatorPageUpdate to enable/disable tools,
144 // even if no item selected
146}
147
148
149void PANEL_REGULATOR::OnDataFileSelection( wxCommandEvent& event )
150{
151 wxString fullfilename = GetDataFilename();
152
153 wxString wildcard;
154 wildcard.Printf( _( "PCB Calculator data file" ) + wxT( " (*.%s)|*.%s" ),
156
157 wxFileDialog dlg( this, _( "Select PCB Calculator Data File" ), wxEmptyString, fullfilename,
158 wildcard, wxFD_OPEN );
159
160 if( dlg.ShowModal() == wxID_CANCEL )
161 return;
162
163 fullfilename = dlg.GetPath();
164
165 if( fullfilename == GetDataFilename() )
166 return;
167
168 SetDataFilename( fullfilename );
169
170 if( wxFileExists( fullfilename ) && m_RegulatorList.GetCount() > 0 ) // Read file
171 {
172 if( wxMessageBox( _( "Do you want to load this file and replace current regulator list?" ) )
173 != wxID_OK )
174 {
175 return;
176 }
177 }
178
179 if( ReadDataFile() )
180 {
185 }
186 else
187 {
188 wxString msg;
189 msg.Printf( _( "Unable to read data file '%s'." ), fullfilename );
190 wxMessageBox( msg );
191 }
192}
193
194
195void PANEL_REGULATOR::OnAddRegulator( wxCommandEvent& event )
196{
197 DIALOG_REGULATOR_FORM dlg( this, wxEmptyString );
198
199 if( dlg.ShowModal() != wxID_OK )
200 return;
201
202 REGULATOR_DATA* new_item = dlg.BuildRegulatorFromData();
203
204 // Add new item, if not existing
205 if( m_RegulatorList.GetReg( new_item->m_Name ) == nullptr )
206 {
207 // Add item in list
208 m_RegulatorList.Add( new_item );
214 }
215 else
216 {
217 wxMessageBox( _( "This regulator is already in list. Aborted" ) );
218 delete new_item;
219 }
220}
221
222
223void PANEL_REGULATOR::OnEditRegulator( wxCommandEvent& event )
224{
225 wxString name = m_choiceRegulatorSelector->GetStringSelection();
227
228 if( item == nullptr )
229 return;
230
231 DIALOG_REGULATOR_FORM dlg( this, name );
232
233 dlg.CopyRegulatorDataToDialog( item );
234
235 if( dlg.ShowModal() != wxID_OK )
236 return;
237
238 REGULATOR_DATA* new_item = dlg.BuildRegulatorFromData();
239 m_RegulatorList.Replace( new_item );
240
242
244}
245
246
247void PANEL_REGULATOR::OnRemoveRegulator( wxCommandEvent& event )
248{
249 wxString name = wxGetSingleChoice( _( "Remove Regulator" ), wxEmptyString,
251 if( name.IsEmpty() )
252 return;
253
258
261
263}
264
265
267{
268 // Find last selected in regulator list:
269 int idx = -1;
270
271 if( !m_lastSelectedRegulatorName.IsEmpty() )
272 {
273 for( unsigned ii = 0; ii < m_RegulatorList.GetCount(); ii++ )
274 {
276 {
277 idx = ii;
278 break;
279 }
280 }
281 }
282
283 m_choiceRegulatorSelector->SetSelection( idx );
284 wxCommandEvent event;
285 OnRegulatorSelection( event );
286}
287
288
290{
291 int id;
292
293 if( m_rbRegulR1->GetValue() )
294 {
295 id = 0; // for R1 calculation
296 }
297 else if( m_rbRegulR2->GetValue() )
298 {
299 id = 1; // for R2 calculation
300 }
301 else if( m_rbRegulVout->GetValue() )
302 {
303 id = 2; // for Vout calculation
304 }
305 else
306 {
307 wxMessageBox( wxT("Selection error" ) );
308 return;
309 }
310
311 double r1, r2, vref, vout;
312
313 wxString txt;
314
315 m_RegulMessage->SetLabel( wxEmptyString);
316
317 // Convert r1 and r2 in ohms
318 int r1scale = 1000;
319 int r2scale = 1000;
320
321 // Read values from panel:
322 txt = m_RegulR1Value->GetValue();
323 r1 = DoubleFromString( txt ) * r1scale;
324 txt = m_RegulR2Value->GetValue();
325 r2 = DoubleFromString( txt ) * r2scale;
326 txt = m_RegulVrefValue->GetValue();
327 vref = DoubleFromString( txt );
328 txt = m_RegulVoutValue->GetValue();
329 vout = DoubleFromString( txt );
330
331 // Some tests:
332 if( vout < vref && id != 2 )
333 {
334 m_RegulMessage->SetLabel( _( "Vout must be greater than vref" ) );
335 return;
336 }
337
338 if( vref == 0.0 )
339 {
340 m_RegulMessage->SetLabel( _( "Vref set to 0 !" ) );
341 return;
342 }
343
344 if( ( r1 < 0 && id != 0 ) || ( r2 <= 0 && id != 1 ) )
345 {
346 m_RegulMessage->SetLabel( _( "Incorrect value for R1 R2" ) );
347 return;
348 }
349
350 // Calculate
351 if( m_choiceRegType->GetSelection() == 1)
352 {
353 // 3 terminal regulator
354 txt = m_RegulIadjValue->GetValue();
355 double iadj = DoubleFromString( txt );
356
357 // iadj is given in micro amp, so convert it in amp.
358 iadj /= 1000000;
359
360 switch( id )
361 {
362 case 0:
363 r1 = vref * r2 / ( vout - vref - ( r2 * iadj ) );
364 break;
365
366 case 1:
367 r2 = ( vout - vref ) / ( iadj + ( vref / r1 ) );
368 break;
369
370 case 2:
371 vout = vref * ( r1 + r2 ) / r1;
372 vout += r2 * iadj;
373 break;
374 }
375 }
376 else
377 { // Standard 4 terminal regulator
378 switch( id )
379 {
380 case 0: r1 = ( vout / vref - 1 ) * r2; break;
381 case 1: r2 = r1 / ( vout / vref - 1 ); break;
382 case 2: vout = vref * ( r1 + r2 ) / r2; break;
383 }
384 }
385
386 // write values to panel:
387 txt.Printf( wxT( "%g" ), r1 / r1scale );
388 m_RegulR1Value->SetValue( txt );
389 txt.Printf( wxT( "%g" ), r2 / r2scale );
390 m_RegulR2Value->SetValue( txt );
391 txt.Printf( wxT( "%g" ), vref );
392 m_RegulVrefValue->SetValue( txt );
393 txt.Printf( wxT( "%g" ), vout );
394 m_RegulVoutValue->SetValue( txt );
395}
396
397
399{
400 // Save current parameter values in config.
401 aCfg->m_Regulators.r1 = m_RegulR1Value->GetValue();
402 aCfg->m_Regulators.r2 = m_RegulR2Value->GetValue();
403 aCfg->m_Regulators.vref = m_RegulVrefValue->GetValue();
404 aCfg->m_Regulators.vout = m_RegulVoutValue->GetValue();
407 aCfg->m_Regulators.type = m_choiceRegType->GetSelection();
408
409 // Store the parameter selection that was recently calculated (R1, R2 or Vout)
410 wxRadioButton* regprms[3] = { m_rbRegulR1, m_rbRegulR2, m_rbRegulVout };
411
412 for( int ii = 0; ii < 3; ii++ )
413 {
414 if( regprms[ii]->GetValue() )
415 {
416 aCfg->m_Regulators.last_param = ii;
417 break;
418 }
419 }
420}
421
422
424{
425 m_RegulR1Value->SetValue( aCfg->m_Regulators.r1 );
426 m_RegulR2Value->SetValue( aCfg->m_Regulators.r2 );
427 m_RegulVrefValue->SetValue( aCfg->m_Regulators.vref );
428 m_RegulVoutValue->SetValue( aCfg->m_Regulators.vout );
431 m_choiceRegType->SetSelection( aCfg->m_Regulators.type );
432
433 wxRadioButton* regprms[3] = { m_rbRegulR1, m_rbRegulR2, m_rbRegulVout };
434
435 if( aCfg->m_Regulators.last_param >= 3 )
436 aCfg->m_Regulators.last_param = 0;
437
438 for( int ii = 0; ii < 3; ii++ )
439 regprms[ii]->SetValue( aCfg->m_Regulators.last_param == ii );
440}
441
442
444{
445 aCfg->m_Regulators.r1 = m_RegulR1Value->GetValue();
446 aCfg->m_Regulators.r2 = m_RegulR2Value->GetValue();
447 aCfg->m_Regulators.vref = m_RegulVrefValue->GetValue();
448 m_RegulVoutValue->SetValue( aCfg->m_Regulators.vout );
451 aCfg->m_Regulators.type = m_choiceRegType->GetSelection();
452
453 wxRadioButton* regprms[3] = { m_rbRegulR1, m_rbRegulR2, m_rbRegulVout };
454
455 aCfg->m_Regulators.last_param = 0;
456
457 for( int ii = 0; ii < 3; ii++ )
458 {
459 if( regprms[ii]->GetValue() )
460 {
461 aCfg->m_Regulators.last_param = ii;
462 break;
463 }
464 }
465}
466
467
469{
470 if( m_regulators_fileNameCtrl->GetValue().IsEmpty() )
471 return wxEmptyString;
472
473 wxFileName fn( m_regulators_fileNameCtrl->GetValue() );
474 fn.SetExt( DataFileNameExt );
475 return fn.GetFullPath();
476}
477
478
479void PANEL_REGULATOR::SetDataFilename( const wxString& aFilename )
480{
481 if( aFilename.IsEmpty() )
482 {
483 m_regulators_fileNameCtrl->SetValue( wxEmptyString );
484 }
485 else
486 {
487 wxFileName fn( aFilename );
488 fn.SetExt( DataFileNameExt );
489 m_regulators_fileNameCtrl->SetValue( fn.GetFullPath() );
490 }
491}
const char * name
Definition: DXF_plotter.cpp:57
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:106
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)
double DoubleFromString(const wxString &TextValue)
double DoubleFromString(const wxString &TextValue)
const wxString DataFileNameExt
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...