diff --git a/Enamel thickness.numbers b/Enamel thickness.numbers new file mode 100755 index 0000000..e4820ee Binary files /dev/null and b/Enamel thickness.numbers differ diff --git a/autotransformer.html b/autotransformer.html new file mode 100644 index 0000000..aa2cd79 --- /dev/null +++ b/autotransformer.html @@ -0,0 +1,2559 @@ + + + + + + VK3CPU RF Auto-Transformer Calculator + + + +
Miguel VK3CPU - RF Auto-Transformer Calculator v0.1a
+
+
+ + 2D Chart Canvas + +
+
+ + +
+
+
+ + + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ Notes:
+ RF Toroid Calculator was developed to help users predict the RF characteristics of a ferrite or powdered-iron toroid wound as an inductor or suppressor. + It uses the manufacturer's (Fair-Rite & Micrometals) published data including the toroid's dimensions and complex permeability characteristics + to predict the component's characteristics.
+ The calculator has 4 separate display areas. At the top is the chart display for showing frequency-dependent characteristics. Next is the + schematic display, where a scaled image of the toroid and windings is presented to help with intuitive design. Next is the control panel + section, where the user can select the application type, toroid material, toroid size, wire size, number of windings and excitation voltage.

+ Inputs via the select widgets: + + Inputs via the slider widgets: + + Note: Manufacturers recommend keeping the number of turns (N) to a minimum.

+ Chart display: + The chart title contains manufacturer, size, material and part number of the device.
+ Calculated parameters are displayed against frequency (log scale). Each parameter may be displayed or hidden + by tapping on the legend key. Tapping on a data point will display the parameters for a single frequency. + +
+ Schematic display: + Scaled representation of the toroid and the windings. Wire gauge and toroid dimensions are provided.
+ On the left of the display are the following: + + In the middle of the display are the following: + + On the right are the manufacturers data for the selected material. + +
+ Observations:
+ Powdered Iron:
+ Inductance and reactance values correspond well with those predicted by online calculators such as toroids.info. + However, predictions for Q have mixed results when compared to the Micrometals Q-Curve Catalog found HERE. + I suggest using their catalog for accurate Q prediction. It has been previously identified that Q values predicted using Micrometal's curve-fit equations do not reconcile with measured Q as discussed here. +

+ TODO:
+ +
+ Change history:
+ [17-Jan-22] - v0.9f
+ * Added x2 and x3 stacking for 31, 43, 52 and 61 240-sized toroids.
+ [24-Nov-21] - v0.9e
+ * Justify tooltips.
+ [14-Nov-21] - v0.9d
+ * Updated manufacturers data section to more-closely match datasheets. Also justify to appear like tabular data.
+ [6-Nov-21] - v0.9c
+ * Re-enabled PI support.
+ * Added support for PI Material 17.
+ [3-Nov-21] - v0.9b
+ * Disabled PI support due to bugs that need to be fixed.
+ [2-Nov-21] - v0.9a
+ * Release 0.9a - Major code refactor to support Powdered Iron toroids.
+ [26-Oct-21]
+ * Increased resolution of the f-slider, making it smoothly regenerate the dataset.
+ [24-Oct-21]
+ * Fixed frozen f-slider issue that was occurring in some browsers running on Windows.
+ * Increased contrast for experimental Ceff and SRF calculations, based on David Knight's (G3YNH) paper.
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/loop6 b/loop6 new file mode 100755 index 0000000..9fe6123 Binary files /dev/null and b/loop6 differ diff --git a/loop6.c b/loop6.c new file mode 100644 index 0000000..8e2a285 --- /dev/null +++ b/loop6.c @@ -0,0 +1,409 @@ +// LOOP6.C by Glen E. Gardner Jr. 08/2014 +// de AA8C +// glen.gardner@verizon.net +// glen.gardner@gridtoys.com + +// to compile: gcc -o loop6 loop6.c -lm + + +#include +#include +#include +#include + + +//declare the needed functions +void data_in(void); +void radr(void); +void skin(void); +void proximity(void); +void efficiency(void); +void inductance(void); +void resonance(void); +void match(void); +void data_out(void); + + +// declare the variables + +// operating frequency +double freq; + +// dynamic resistance of the LC circuit +double DR; + +// transmitter power +double PO; + +// voltage on the capacitor at 100 watts +double VMAX; + +// wavelength +double la; + +// Q of the antenna +double Q; + +// 2:1 SWR bandwidth of the antenna +double SWR; + +// 6 dB bandwidth of the antenna +double bw; + +// estimated efficiency +double eff; + +// resistivity of 6061-T6 aluminum alloy +double o; + +// reciprocal of the resistivity +// conductivity +double oo; + +// resistivity of skin effect +double Rs; + +// rf loss resistance for skin effect +double Rhf; + +// combined rf loss resistance for +// skin effect and proximity effect +double Rhf2; + +// permeability of free space +double u; + +// relative permeability of aluminum +double ur; + +// diameter of the loop +double D; + +// radius of the loop +double Ra; + +// circumference of the loop +double CIR; + +// area of the loop +double A; + +// width of the loop +double W; + +// height of the loop +double H; + +// diameter of the loop conductor +double d; + +// radius of the loop conductor +double ra; + +// cross-sectional area of the loop conductor +double a; + +// radius of the loop conductor +double r; + +// circumference of the loop conductor +double cir; + +// series input impedance +double Zin; + +// rf resistance loss +double Rrf; + +// inductance of a loop +double L; + +// conductor inductance +double Lc; + +// inductive reactance of a loop +double Xl; + +// Capacitance +double C; + +// capacative reactance +double Xc; + +// radiation resistance +double Rr; + +// loop series impedance +double Z; + +// area of pickup loop +double area; + +// number of loops +double N; + +// coefficient of coupling +double K; + + +// low frequency limit +double low; + +// high frequency limit +double high; + +// frequency step +double step; + +char type[256]; + +int main(void) +{ +double la2; +int i; + + + +// get the needed input +data_in(); + + +//A=0.660644; +// resistivity of aluminum +//o=0.000000037; +// resistivity of copper +//o=0.0000000168; + +// conductivity +oo=1/o; + +//free space permeability +u=4*M_PI*pow(10,-7); + +// the relative permeability of aluminum +//ur=1.000022; +// the relative permeability of copper +// ur=0.999994; + +//CIR=3.2512; +//d=0.0111125; +r=d/2; +cir=M_PI*d; + + +//K=0.427139; +//Ra=D/2; + + + + +freq=low; +while(freq < high) +{ + +la=300000000/freq; +la2=la/2; + +if(!strcasecmp(type,"SQUARE")){D=CIR/4;Ra=D/2;A=D*D;} +if(!strcasecmp(type,"CIRCLE")){D=CIR/M_PI;Ra=D/2;A=M_PI*Ra*Ra;} + +// calculate the radiation resistance + radr(); + +// add skin effect to Rrf +skin(); + +// if more than one loop is present, estimate the proximity effect +if(N>1)proximity(); + +// calculate the efficiency of the loop +efficiency(); + +// calculate the inductance of the loop +inductance(); + +// calculate the reactance of the loop +// as well as series input impedance +resonance(); + +// calculate the area of the small coupling loop +match(); + +// print out much preformatted data +data_out(); + +freq=freq+step; +} + +} + + +void data_in(void) +{ + +printf("LOOP TYPE (CIRCLE or SQUARE): "); +scanf("%s",&type); +//printf("type %s\n",type); +printf("LOOP CIRCUMFERENCE(METERS): "); +scanf("%lf",&CIR); + +printf("CONDUCTOR DIAMETER(METERS): "); +scanf("%lf",&d); + +printf("NUMBER OF LOOP CONDUCTORS: "); +scanf("%lf",&N); + +printf("RESISTIVITY OF LOOP MATERIAL (OHM-METER): "); +scanf("%lf",&o); + +printf("RELATIVE PERMEABILITY OF LOOP MATERIAL: "); +scanf("%lf",&ur); + +K=1; + +if(N>1) +{ +printf("LOOP COEFFICIENT OF COUPLING (K>=1/N,K<=1): "); +scanf("%lf",&K); + +} + +printf("TRANSMITTER POWER (WATTS): "); +scanf("%lf",&PO); + +printf("LOW FREQUENCY LIMIT (MHz): "); +scanf("%lf",&low); +low=low*1000000; + +printf("HIGH FREQUENCY LIMIT (MHz): "); +scanf("%lf",&high); +high=high*1000000; + +printf("FREQUENCY STEP (MHz): "); +scanf("%lf",&step); +step=step*1000000; + +} + + +void radr(void) +{ +// radiation resistance for a single loop +// This is the favored model for radiation resistance in a loop +// It is problematic in that it is an approximation, and it is not +// correct in the case of a square loop. + +Rr=31171*((A*A)/(la*la*la*la)); + +// It turns out that the radiation resistance for a round loop +// is very close to 1.621 times greater than that of a square loop. +// +// correction for a square loop +if(!strcasecmp(type,"SQUARE"))Rr=Rr/1.621; + +// radiation resistance increases directly with the +// the number of parallel loops +// so we need to adjust it. +Rr=Rr*N; +} + +void skin(void) +{ + +//double i; + +// This is the standard model for skin effect +// +Rs=sqrt((M_PI*freq*u*ur)/oo); + +Rhf=(CIR/cir)*Rs; + +// the rf resistance loss decreases as +// the number of loops increase. +// +Rhf2=Rhf/N; + +} + +void proximity(void) +{ +double Ro; +double Rp; +double Rpo; + +Ro=Rhf/CIR; + +// This parameter is estimated based on Glen Smith ,1971 +// This ends up being a little contrived, but will work +// provided that the antenna is built with the spacing +// between conductors equal to or greater than that +// recommended by Smith. +// + +// Yes. Yet another approximation. +// Boldly assuming that the increase in proximity +// effect is close to N cubed! +Rpo=0.003*N*N*N; +//Rpo=1; + +Rp=Ro*Rpo; + +Rhf2=(Rp+Ro)*CIR; + +} + +void efficiency(void) +{ +// ground effects are ignored in this case +eff=Rr/(Rr+Rhf2); +} + +void inductance(void) +{ + +// This is for a circular loop +L=Ra*u*ur*(log((8*Ra)/r)-2); + +// This is for a square loop +if(!strcasecmp(type,"SQUARE"))L=((2*u*ur*D)/M_PI)*(log(D/r)-0.77401); + +// adjust for the coefficient of coupling in parallel conductor loops +if(N>1)L=L/(N*K); +} + + +void match(void) +{ +double Zin=50.0; + +area=A*(Z/sqrt(Zin)); + +} + +void resonance(void) +{ +Xl=2*M_PI*freq*L; +Z=sqrt(Rr+Rhf2); +Xc=Xl; +C=(1/Xc)/(2*M_PI*freq); +Q=Xl/(2*(Rr+ Rhf2)); +bw=(freq/Q)/1000; +SWR=2*(bw/(3/0.512)); +DR=Xl*Q; +VMAX=sqrt(PO*DR); +} + +void data_out(void) +{ +//freq=freq/1000000; +printf(" Frequency: %3.3f MHz Rr: %4.4f ohm\n",freq/1000000,Rr+0.00004); +printf(" Rhf2: %4.4f ohm Efficiency: %0.4f\n",Rhf2+0.00004,eff+0.00004); +L=L*1000000; +C=C*1000000000000; +printf(" L: %4.4f uH Xl: %4.4f ohm C: %4.1f pF\n",L+0.00004,Xl+0.00004,C+0.04); +printf(" Z: %4.4f ohm Q: %4.4f\n",Z,Q); +printf(" Bandwidth: %6.4f KHz. 2:1 SWR Bandwidth: %6.4f KHz\n",bw+0.00004,SWR+0.00004); +printf(" Dynamic Resistance: %6.2f Ohm. Potential across the Capacitor: %6.2f Volt\n",DR+0.004,VMAX+0.004); +printf(" Pickup loop area: %4.4f square meters\n\n",area+0.00004); +} + diff --git a/magloop.html b/magloop.html index 846afc1..630003e 100644 --- a/magloop.html +++ b/magloop.html @@ -209,7 +209,60 @@ var imperial_radio = document.getElementById("imperial_radio"); var shape_radio = document.getElementById("shape_radio"); var external_losses_slider = document.getElementById("external_losses_slider"); + + const params_to_sliders = { + loop_diameter: loop_diameter_slider, + conductor_diameter: conductor_diameter_slider, + loop_turns: loop_turns_slider, + loop_spacing: loop_spacing_slider, + transmit_power: transmit_power_slider, + external_losses: external_losses_slider, + } + const sliders_to_params = Object.entries(params_to_sliders).map(([k, v]) => [v, k]); + + const params_to_radio_names = { + unit: "unit_radio", + metal: "metal_radio", + shape: "shape_radio", + } + const radio_names_to_params = Object.entries(params_to_radio_names).map(([k, v]) => [v, k]); + + // If there's a query param in the URL, set each slider's value to the respective params. + for (const [key, value] of new URLSearchParams(window.location.search)) { + var slider = params_to_sliders[key]; + if (slider) { + slider.value = value; + } + + var radio_name = params_to_radio_names[key]; + if (radio_name) { + // Find all radio elements with this name, set each checked status to the current value. + var radios = document.getElementsByName(radio_name); + for (var i = 0; i < radios.length; i++) { + radios[i].checked = (radios[i].value == value); + } + } + } + // Function to call after a successful recalculation + const updateURL = function() { + const usp = new URLSearchParams(); + for (const [slider, param] of sliders_to_params) { + if (slider == null) continue; + var value = slider.value; + usp.set(param, value); + } + + for (const [radio_name, param] of radio_names_to_params) { + var radio = document.querySelector(`input[type=radio][name=${radio_name}]:checked`); + usp.set(param, radio.value); + } + + var new_url = new URL(window.location.href); + new_url.search = usp; + window.history.replaceState(null, null, new_url); + } + // Global variables: var units = "metric"; var conductivity = 58e6; // Default is annealed copper @@ -617,6 +670,7 @@ setGlobals(); drawFrontDesign(); drawSideDesign(); + updateURL(); } imperial_radio.oninput = function() { @@ -624,6 +678,7 @@ //console.log(units); drawFrontDesign(); drawSideDesign(); + updateURL(); } copper_radio.oninput = function() { @@ -645,6 +700,7 @@ myChart.data.datasets[9].data = calculateAntennaSize(); myChart.data.datasets[10].data = calculateSkinDepth(); myChart.update(); + updateURL(); } aluminium_radio.oninput = function() { @@ -666,6 +722,7 @@ myChart.data.datasets[9].data = calculateAntennaSize(); myChart.data.datasets[10].data = calculateSkinDepth(); myChart.update(); + updateURL(); } circle_radio.oninput = function() { @@ -686,6 +743,7 @@ myChart.data.datasets[9].data = calculateAntennaSize(); myChart.data.datasets[10].data = calculateSkinDepth(); myChart.update(); + updateURL(); } oct_radio.oninput = function() { @@ -706,6 +764,7 @@ myChart.data.datasets[9].data = calculateAntennaSize(); myChart.data.datasets[10].data = calculateSkinDepth(); myChart.update(); + updateURL(); } hex_radio.oninput = function() { @@ -726,6 +785,7 @@ myChart.data.datasets[9].data = calculateAntennaSize(); myChart.data.datasets[10].data = calculateSkinDepth(); myChart.update(); + updateURL(); } square_radio.oninput = function() { @@ -746,6 +806,7 @@ myChart.data.datasets[9].data = calculateAntennaSize(); myChart.data.datasets[10].data = calculateSkinDepth(); myChart.update(); + updateURL(); } // Specify fonts for changing parameters controlled by the sliders: @@ -795,6 +856,7 @@ myChart.data.datasets[9].data = calculateAntennaSize(); myChart.data.datasets[10].data = calculateSkinDepth(); myChart.update(); + updateURL(); } var cond_dia_timer_handler = 0; @@ -835,6 +897,7 @@ myChart.data.datasets[9].data = calculateAntennaSize(); myChart.data.datasets[10].data = calculateSkinDepth(); myChart.update(); + updateURL(); } var turns_timer_handler = 0; @@ -873,6 +936,7 @@ myChart.data.datasets[9].data = calculateAntennaSize(); myChart.data.datasets[10].data = calculateSkinDepth(); myChart.update(); + updateURL(); } var spacing_timer_handler = 0; @@ -913,6 +977,7 @@ myChart.data.datasets[9].data = calculateAntennaSize(); myChart.data.datasets[10].data = calculateSkinDepth(); myChart.update(); + updateURL(); } var tx_timer_handler = 0; @@ -940,6 +1005,7 @@ myChart.data.datasets[1].data = calculateCapacitorVoltage(); myChart.data.datasets[8].data = calculateCirculatingCurrent(); myChart.update(); + updateURL(); } var external_losses_handler = 0; @@ -970,6 +1036,7 @@ myChart.data.datasets[7].data = calculateQualityFactor(); myChart.data.datasets[8].data = calculateCirculatingCurrent(); myChart.update(); + updateURL(); } window.onresize = function() { @@ -1927,4 +1994,4 @@ }); - \ No newline at end of file + diff --git a/mom_test.py b/mom_test.py new file mode 100644 index 0000000..67a92fb --- /dev/null +++ b/mom_test.py @@ -0,0 +1,20 @@ +# Program to develop and test algorithms for MoM antenna calculator +import numpy as np + +# var t_seg = {}; +# t_seg.start = wire.points[m-1]; +# t_seg.end = wire.points[m+1]; +# t_seg.mid = wire.points[m]; +# t_seg.len = wire.seg_len; +# t_seg.radius = wire.radius; +# t_seg.feedpoint = false; +# segments.push(t_seg); + +t_seg = {} +t_seg['start'] = [0.11, 0.0, 0.0] +t_seg['end'] = [0.15, 0.0, 0.0] +t_seg['mid'] = [0.13, 0.0, 0.0] +t_seg['len'] = 0.040 +t_seg['radius'] = 0.002 + +tp1 = [0.0, 100.0, 100.0] diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..a4ec5c9 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,39 @@ +{ + "name": "vk3cpu", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "devDependencies": { + "@types/dat.gui": "^0.7.7", + "dat.gui": "^0.7.9" + } + }, + "node_modules/@types/dat.gui": { + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/@types/dat.gui/-/dat.gui-0.7.7.tgz", + "integrity": "sha512-CxLCme0He5Jk3uQwfO/fGZMyNhb/ypANzqX0yU9lviBQMlen5SOvQTBQ/Cd9x5mFlUAK5Tk8RgvTyLj1nYkz+w==", + "dev": true + }, + "node_modules/dat.gui": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/dat.gui/-/dat.gui-0.7.9.tgz", + "integrity": "sha512-sCNc1OHobc+Erc1HqiswYgHdVNpSJUlk/Hz8vzOCsER7rl+oF/4+v8GXFUyCgtXpoCX6+bnmg07DedLvBLwYKQ==", + "dev": true + } + }, + "dependencies": { + "@types/dat.gui": { + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/@types/dat.gui/-/dat.gui-0.7.7.tgz", + "integrity": "sha512-CxLCme0He5Jk3uQwfO/fGZMyNhb/ypANzqX0yU9lviBQMlen5SOvQTBQ/Cd9x5mFlUAK5Tk8RgvTyLj1nYkz+w==", + "dev": true + }, + "dat.gui": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/dat.gui/-/dat.gui-0.7.9.tgz", + "integrity": "sha512-sCNc1OHobc+Erc1HqiswYgHdVNpSJUlk/Hz8vzOCsER7rl+oF/4+v8GXFUyCgtXpoCX6+bnmg07DedLvBLwYKQ==", + "dev": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..a177f3d --- /dev/null +++ b/package.json @@ -0,0 +1,6 @@ +{ + "devDependencies": { + "@types/dat.gui": "^0.7.7", + "dat.gui": "^0.7.9" + } +} diff --git a/transf.js b/transf.js new file mode 100644 index 0000000..dd1252d --- /dev/null +++ b/transf.js @@ -0,0 +1,55 @@ +// Import React and ReactDOM libraries +import React from 'react'; +import ReactDOM from 'react-dom'; + +// Import Slider component from react-slider library +import Slider from 'react-slider'; + +// Define a custom component that renders a slider with some props +class MySlider extends React.Component { + constructor(props) { + super(props); + // Set the initial state of the slider value + this.state = { + value: props.defaultValue || 0 + }; + } + + // Define a handler function that updates the state when the slider changes + handleChange = (value) => { + this.setState({ value }); + }; + + // Define a render function that returns the JSX element for the slider + render() { + return ( +
+

{this.props.label}: {this.state.value}

+ +
+ ); + } +} + +// Define the main App component that renders multiple sliders +class App extends React.Component { + render() { + return ( +
+

React Slider Example

+ + + +
+ ); + } +} + +// Render the App component to the root element in the HTML document +ReactDOM.render(, document.getElementById('root'));