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.

235 lines
8.9 KiB

  1. /*
  2. * This program source code file is part of KiCad, a free EDA CAD application.
  3. *
  4. * Copyright (C) 2020 <janvi@veith.net>
  5. * Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors.
  6. *
  7. * This program is free software: you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the
  9. * Free Software Foundation, either version 3 of the License, or (at your
  10. * option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * 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. extern double DoubleFromString( const wxString& TextValue );
  21. /**
  22. * If BENCHMARK is defined, any 4R E12 calculations will print its execution time to console
  23. * My Hasswell Enthusiast reports 225 mSec what are reproducable within plusminus 2 percent
  24. */
  25. //#define BENCHMARK
  26. /**
  27. * E-Values derived from a geometric sequence formula by Charles Renard were already
  28. * accepted and widely used before the ISO recommendation no. 3 has been published.
  29. * For this historical reason, rounding rules of some values are sometimes irregular.
  30. * Although all E-Values could be calculated at runtime, we initialize them in a lookup table
  31. * what seems the most easy way to consider any inconvenient irregular rules. Same table is
  32. * also used to lookup non calculatable but readable BOM value strings. Supported E-series are:
  33. */
  34. enum { E1, E3, E6, E12 };
  35. /**
  36. * This calculator suggests solutions for 2R, 3R and 4R replacement combinations
  37. */
  38. enum { S2R, S3R, S4R };
  39. /**
  40. * 6 decade E-series values from 10 Ohms to 1M and its associated BOM strings.
  41. * Series E3,E6,E12 are defined by additional values for cumulative use with previous series
  42. */
  43. #define E1_VAL { true, "1K", 1000 },\
  44. { true, "10K", 10000 },\
  45. { true, "100K", 100000 },\
  46. { true, "10R", 10 },\
  47. { true, "100R", 100 },\
  48. { true, "1M", 1000000 }
  49. #define E3_ADD { true, "22R", 22 },\
  50. { true, "47R", 47 },\
  51. { true, "220R", 220 },\
  52. { true, "470R", 470 },\
  53. { true, "2K2", 2200 },\
  54. { true, "4K7", 4700 },\
  55. { true, "22K", 22000 },\
  56. { true, "47K", 47000 },\
  57. { true, "220K", 220000 },\
  58. { true, "470K", 470000 }
  59. #define E6_ADD { true, "15R", 15 },\
  60. { true, "33R", 33 },\
  61. { true, "68R", 68 },\
  62. { true, "150R", 150 },\
  63. { true, "330R", 330 },\
  64. { true, "680R", 680 },\
  65. { true, "1K5", 1500 },\
  66. { true, "3K3", 3300 },\
  67. { true, "6K8", 6800 },\
  68. { true, "15K", 15000 },\
  69. { true, "33K", 33000 },\
  70. { true, "68K", 68000 },\
  71. { true, "150K", 150000 },\
  72. { true, "330K", 330000 },\
  73. { true, "680K", 680000 }
  74. #define E12_ADD { true, "12R", 12 },\
  75. { true, "18R", 18 },\
  76. { true, "27R", 27 },\
  77. { true, "39R", 39 },\
  78. { true, "56R", 56 },\
  79. { true, "82R", 82 },\
  80. { true, "120R", 120 },\
  81. { true, "180R", 180 },\
  82. { true, "270R", 270 },\
  83. { true, "390R", 390 },\
  84. { true, "560R", 560 },\
  85. { true, "820R", 820 },\
  86. { true, "1K2", 1200 },\
  87. { true, "1K8", 1800 },\
  88. { true, "2K7", 2700 },\
  89. { true, "3K9", 3900 },\
  90. { true, "5K6", 5600 },\
  91. { true, "8K2", 8200 },\
  92. { true, "12K", 12000 },\
  93. { true, "18K", 18000 },\
  94. { true, "27K", 27000 },\
  95. { true, "39K", 39000 },\
  96. { true, "56K", 56000 },\
  97. { true, "82K", 82000 },\
  98. { true, "120K", 120000 },\
  99. { true, "180K", 180000 },\
  100. { true, "270K", 270000 },\
  101. { true, "390K", 390000 },\
  102. { true, "560K", 560000 },\
  103. { true, "820K", 820000 }
  104. struct r_data {
  105. bool e_use;
  106. std::string e_name;
  107. double e_value;
  108. };
  109. class eserie
  110. {
  111. public:
  112. /**
  113. * If any value of the selected E-serie not available, it can be entered as an exclude value.
  114. *
  115. * @param aValue is the value to exclude from calculation
  116. * Values to exclude are set to false in the selected E-serie source lookup table
  117. */
  118. void Exclude( double aValue );
  119. /**
  120. * initialize next calculation and erase results from previous calculation
  121. */
  122. void NewCalc( void );
  123. /**
  124. * called on calculate button to execute all the 2R, 3R and 4R calculations
  125. */
  126. void Calculate( void );
  127. /**
  128. * Interface for CheckBox, RadioButton, RequriedResistor and calculated Results
  129. */
  130. void SetSeries( uint32_t aSeries ) { m_series = aSeries; }
  131. void SetRequiredValue( double aValue ) { m_required_value = aValue; }
  132. std::array<r_data,S4R+1> get_rslt( void ) { return m_results; }
  133. private:
  134. /**
  135. * Build all 2R combinations from the selected E-serie values
  136. *
  137. * Pre-calculated value combinations are saved in intermediate look up table m_cmb_lut
  138. * @return is the number of found combinations what also depends from exclude values
  139. */
  140. uint32_t combine2( void );
  141. /**
  142. * Search for closest two component solution
  143. *
  144. * @param aSize is the number of valid 2R combinations in m_cmb_lut on where to search
  145. * The 2R result with smallest deviation will be saved in results
  146. */
  147. void simple_solution( uint32_t aSize );
  148. /**
  149. * Check if there is a better 3 R solution than previous one using only two components.
  150. *
  151. * @param aSize gives the number of available combinations to be checked inside m_cmb_lut
  152. * Therefore m_cmb_lut is combinated with the primary E-serie look up table
  153. * The 3R result with smallest deviation will be saved in results if better than 2R
  154. */
  155. void combine3( uint32_t aSize );
  156. /**
  157. * Check if there is a better four component solution.
  158. *
  159. * @param aSsize gives the number of 2R combinations to be checked inside m_cmb_lut
  160. * Occupied calculation time depends from number of available E-serie values
  161. * with the power of 4 why execution for E12 is conditional with 4R check box
  162. * for the case the previously found 3R solution is already exact
  163. */
  164. void combine4( uint32_t aSize );
  165. /*
  166. * Strip redundant braces from three component result
  167. *
  168. * Example: R1+(R2+R3) become R1+R2+R3
  169. * and R1|(R2|R3) become R1|R2|R3
  170. * while R1+(R2|R3) or (R1+R2)|R3) remains untouched
  171. */
  172. void strip3( void );
  173. /*
  174. * Strip redundant braces from four component result
  175. *
  176. * Example: (R1+R2)+(R3+R4) become R1+R2+R3+R4
  177. * and (R1|R2)|(R2|R3) become R1|R2|R3|R4
  178. * while (R1+R2)|(R3+R4) remains untouched
  179. */
  180. void strip4( void );
  181. private:
  182. std::vector<std::vector<r_data>> luts {
  183. { E1_VAL },
  184. { E1_VAL, E3_ADD },
  185. { E1_VAL, E3_ADD, E6_ADD },
  186. { E1_VAL, E3_ADD, E6_ADD, E12_ADD }
  187. };
  188. /*
  189. * TODO: Manual array size calculation is dangerous. Unlike legacy ANSI-C Arrays
  190. * std::array can not drop length param by providing aggregate init list up
  191. * to C++17. Reserved array size should be 2*E12² of std::vector primary list.
  192. * Exceeding memory limit 7442 will crash the calculator without any warnings !
  193. * Compare to previous MAX_COMB macro for legacy ANSI-C array automatic solution
  194. * #define E12_SIZE sizeof ( e12_lut ) / sizeof ( r_data )
  195. * #define MAX_COMB (2 * E12_SIZE * E12_SIZE)
  196. * 2 component combinations including redundant swappable terms are for the moment
  197. * 72 combinations for E1
  198. * 512 combinations for E3
  199. * 1922 combinations for E6
  200. * 7442 combinations for E12
  201. */
  202. #define MAX_CMB 7442 // maximum combinations for E12
  203. std::array<r_data, MAX_CMB> m_cmb_lut; // intermediate 2R combinations
  204. std::array<r_data, S4R+1> m_results; // 2R, 3R and 4R results
  205. uint32_t m_series = E6; // Radio Button State
  206. uint32_t m_enable_4R = false; // Check Box 4R enable
  207. double m_required_value; // required Resistor
  208. };