You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							187 lines
						
					
					
						
							6.2 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							187 lines
						
					
					
						
							6.2 KiB
						
					
					
				
								/*
							 | 
						|
								 * This program source code file
							 | 
						|
								 * is part of KiCad, a free EDA CAD application.
							 | 
						|
								 *
							 | 
						|
								 * Copyright (C) 2023 KiCad Developers, see AUTHORS.txt for contributors.
							 | 
						|
								 *
							 | 
						|
								 * This program is free software: you can redistribute it and/or modify it
							 | 
						|
								 * under the terms of the GNU General Public License as published by the
							 | 
						|
								 * Free Software Foundation, either version 3 of the License, or (at your
							 | 
						|
								 * option) any later version.
							 | 
						|
								 *
							 | 
						|
								 * This program is distributed in the hope that it will be useful, but
							 | 
						|
								 * WITHOUT ANY WARRANTY; without even the implied warranty of
							 | 
						|
								 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
							 | 
						|
								 * General Public License for more details.
							 | 
						|
								 *
							 | 
						|
								 * You should have received a copy of the GNU General Public License along
							 | 
						|
								 * with this program.  If not, see <http://www.gnu.org/licenses/>.
							 | 
						|
								 */
							 | 
						|
								
							 | 
						|
								#pragma once
							 | 
						|
								
							 | 
						|
								#include <string>
							 | 
						|
								#include <cstdint>
							 | 
						|
								#include <vector>
							 | 
						|
								#include <array>
							 | 
						|
								#include "eseries.h"
							 | 
						|
								
							 | 
						|
								// First value of resistor in ohm
							 | 
						|
								// This value is only pertinent to the resistor calculator.
							 | 
						|
								// It is used to reduce the computational complexity of its calculations.
							 | 
						|
								// There are valid resistor values using E-series numbers below this
							 | 
						|
								// value and above the below LAST_VALUE.
							 | 
						|
								#define FIRST_VALUE 10
							 | 
						|
								
							 | 
						|
								// last value of resistor in ohm
							 | 
						|
								// This value is only pertinent to the resistor calculator. See above.
							 | 
						|
								#define LAST_VALUE 1e6
							 | 
						|
								
							 | 
						|
								// R_DATA handles a resistor: 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;
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								class RES_EQUIV_CALC
							 | 
						|
								/*! \brief Performs calculations on E-series values primarily to find target values.
							 | 
						|
								 *
							 | 
						|
								 * E_SERIES class stores and performs calcuations on E-series values. It currently
							 | 
						|
								 * is targeted toward the resistor calculator and hard codes some limitations
							 | 
						|
								 * to optimize its use in the resistor calculator.
							 | 
						|
								 *
							 | 
						|
								 * At this time these limitations are that this class ignores all E-series larger
							 | 
						|
								 * than E24 and it does not consider resistor values below 10 Ohm or above 1M Ohm.
							 | 
						|
								 */
							 | 
						|
								{
							 | 
						|
								public:
							 | 
						|
								    RES_EQUIV_CALC();
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     * This calculator suggests solutions for 2R, 3R and 4R replacement combinations
							 | 
						|
								     */
							 | 
						|
								    enum
							 | 
						|
								    {
							 | 
						|
								        S2R,
							 | 
						|
								        S3R,
							 | 
						|
								        S4R
							 | 
						|
								    };
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     * If any value of the selected E-series not available, it can be entered as an exclude value.
							 | 
						|
								     *
							 | 
						|
								     * @param aValue is the value to exclude from calculation
							 | 
						|
								     * Values to exclude are set to false in the selected E-series source lookup table
							 | 
						|
								     */
							 | 
						|
								    void Exclude( double aValue );
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     *  initialize next calculation and erase results from previous calculation
							 | 
						|
								     */
							 | 
						|
								    void NewCalc();
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     * called on calculate button to execute all the 2R, 3R and 4R calculations
							 | 
						|
								     */
							 | 
						|
								    void Calculate();
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     * Interface for CheckBox, RadioButton, RequriedResistor and calculated Results
							 | 
						|
								     */
							 | 
						|
								    void SetSeries( uint32_t aSeries ) { m_series = aSeries; }
							 | 
						|
								    void SetRequiredValue( double aValue ) { m_required_value = aValue; }
							 | 
						|
								
							 | 
						|
								    // Accessor:
							 | 
						|
								    const std::array<R_DATA, S4R + 1>& GetResults() { return m_results; }
							 | 
						|
								
							 | 
						|
								private:
							 | 
						|
								    /**
							 | 
						|
								     * Add values from aList to m_tables.  Covers all decades between FIRST_VALUE and LAST_VALUE.
							 | 
						|
								     * @return the count of items added to m_tables.
							 | 
						|
								     */
							 | 
						|
								    int buildSeriesData( const ESERIES::ESERIES_VALUES );
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     * Build all 2R combinations from the selected E-series values
							 | 
						|
								     *
							 | 
						|
								     * Pre-calculated value combinations are saved in intermediate look up table m_combined_table
							 | 
						|
								     * @return is the number of found combinations what also depends from exclude values
							 | 
						|
								    */
							 | 
						|
								    uint32_t combine2();
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     * Search for closest two component solution
							 | 
						|
								     *
							 | 
						|
								     * @param aSize is the number of valid 2R combinations in m_combined_table on where to search
							 | 
						|
								     * The 2R result with smallest deviation will be saved in results
							 | 
						|
								    */
							 | 
						|
								    void simple_solution( uint32_t aSize );
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     * Check if there is a better 3 R solution than previous one using only two components.
							 | 
						|
								     *
							 | 
						|
								     * @param aSize gives the number of available combinations to be checked inside
							 | 
						|
								     *              m_combined_table.  Therefore m_combined_table is combined with the primary
							 | 
						|
								     *              E-series look up table.  The 3R result with smallest deviation will be saved
							 | 
						|
								     *              in results if better than 2R
							 | 
						|
								     */
							 | 
						|
								    void combine3( uint32_t aSize );
							 | 
						|
								
							 | 
						|
								    /**
							 | 
						|
								     * Check if there is a better four component solution.
							 | 
						|
								     *
							 | 
						|
								     * @param aSsize gives the number of 2R combinations to be checked inside m_combined_table
							 | 
						|
								     * Occupied calculation time depends from number of available E-series values with the power
							 | 
						|
								     * of 4 why execution for E12 is conditional with 4R check box for the case the previously
							 | 
						|
								     * found 3R solution is already exact
							 | 
						|
								     */
							 | 
						|
								    void combine4( uint32_t aSize );
							 | 
						|
								
							 | 
						|
								    /*
							 | 
						|
								     * Strip redundant braces from three component result
							 | 
						|
								     *
							 | 
						|
								     * Example: R1+(R2+R3) become R1+R2+R3
							 | 
						|
								     * and      R1|(R2|R3) become R1|R2|R3
							 | 
						|
								     * while    R1+(R2|R3) or (R1+R2)|R3) remains untouched
							 | 
						|
								     */
							 | 
						|
								    void strip3();
							 | 
						|
								
							 | 
						|
								    /*
							 | 
						|
								     * Strip redundant braces from four component result
							 | 
						|
								     *
							 | 
						|
								     * Example: (R1+R2)+(R3+R4) become R1+R2+R3+R4
							 | 
						|
								     * and      (R1|R2)|(R2|R3) become R1|R2|R3|R4
							 | 
						|
								     * while    (R1+R2)|(R3+R4) remains untouched
							 | 
						|
								     */
							 | 
						|
								    void strip4();
							 | 
						|
								
							 | 
						|
								private:
							 | 
						|
								    std::vector<std::vector<R_DATA>> m_tables;
							 | 
						|
								
							 | 
						|
								    /* Note: intermediate calculations use m_combined_table
							 | 
						|
								     * 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_combined_table;               // intermediate 2R combinations
							 | 
						|
								
							 | 
						|
								    std::array<R_DATA, S4R + 1> m_results;              // 2R, 3R and 4R results
							 | 
						|
								    uint32_t                    m_series = ESERIES::E6; // Radio Button State
							 | 
						|
								    double                      m_required_value = 0.0; // required Resistor
							 | 
						|
								};
							 |