kopia lustrzana https://github.com/miguelvaca/vk3cpu
rodzic
83caed38f1
commit
ea5af6c249
|
@ -6,6 +6,7 @@ header {
|
|||
background: black;
|
||||
color: white;
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
font-size: smaller;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
@ -47,12 +48,13 @@ section.spreadsheet div.first-col {
|
|||
|
||||
section.controls div {
|
||||
background:yellow;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
section.controls div label {
|
||||
background:rgb(94, 245, 94);
|
||||
display: inline-block;
|
||||
width: 180px;
|
||||
width: 150px;
|
||||
font-size: 0.8em;
|
||||
text-align: right;
|
||||
}
|
||||
|
@ -60,7 +62,7 @@ section.controls div label {
|
|||
section.controls div input {
|
||||
background:lightsalmon;
|
||||
display: inline-block;
|
||||
width: 300px;
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
footer {
|
||||
|
|
135
magloop.html
135
magloop.html
|
@ -7,16 +7,17 @@
|
|||
<link rel="stylesheet" href="magloop.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>Miguel VK3CPU - Magloop Antenna Calculator</header>
|
||||
<header>VK3CPU - Small Loop Antenna Calculator</header>
|
||||
<!--
|
||||
<canvas id="3Dantenna" height="200px">
|
||||
3D Antenna Radiation Pattern Canvas
|
||||
</canvas>
|
||||
-->
|
||||
<svg >
|
||||
<circle cx="50%" cy="50%" r="30%" stroke="black" stroke-width="3" fill="white"/>
|
||||
<circle cx="50%" cy="50%" r="25%" stroke="black" stroke-width="3" fill="white"/>
|
||||
<text x="78%" y="50%" style="fill:black;">Capacitance</text>
|
||||
<circle cx="25%" cy="50%" r="40" stroke="black" stroke-width="2" fill="white"/>
|
||||
<circle cx="25%" cy="50%" r="35" stroke="black" stroke-width="2" fill="white"/>
|
||||
<text x="08%" y="50%" style="fill:black;">⌀ 1</text>
|
||||
<line x1="40" y1="50%" x2="80" y2="50%" style="stroke:rgb(0,0,0);stroke-width:2" />
|
||||
</svg>
|
||||
<canvas id="chartCanvas">
|
||||
2D Chart Canvas
|
||||
|
@ -37,6 +38,11 @@
|
|||
<input type="range" id="loop_turns_slider" min="1" max="8" value="1.0" step="1.0">
|
||||
<span id="loop_turns_value"></span>
|
||||
</div>
|
||||
<div>
|
||||
<label for="loop_spacing_slider">Loop spacing ratio:</label>
|
||||
<input type="range" id="loop_spacing_slider" min="1.1" max="4.0" value="2.0" step="0.05">
|
||||
<span id="loop_spacing_value"></span>
|
||||
</div>
|
||||
<div>
|
||||
<label for="transmit_power_slider">Transmit Power:</label>
|
||||
<input type="range" id="transmit_power_slider" min="25" max="1500" value="400" step="25">
|
||||
|
@ -48,14 +54,11 @@
|
|||
<span id="heightAboveGround_value"></span> (m)
|
||||
</div>
|
||||
</section>
|
||||
<footer>
|
||||
<p>Footer</p>FFF
|
||||
</footer>
|
||||
</body>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
|
||||
<script>
|
||||
const frequencies = [
|
||||
1.8, 3.5, 7.0, 10.1, 14.0, 18.068, 21.0, 24.89, 28.0
|
||||
1.8, 2.2, 2.5, 3.5, 5.0, 7.0, 10.1, 14.0, 18.068, 21.0, 24.89, 28.0
|
||||
];
|
||||
|
||||
var loop_diameter_slider = document.getElementById("loop_diameter_slider");
|
||||
|
@ -70,6 +73,10 @@
|
|||
var loop_turns_value = document.getElementById("loop_turns_value");
|
||||
loop_turns_value.innerHTML = loop_turns_slider.value;
|
||||
|
||||
var loop_spacing_slider = document.getElementById("loop_spacing_slider");
|
||||
var loop_spacing_value = document.getElementById("loop_spacing_value");
|
||||
loop_spacing_value.innerHTML = loop_spacing_slider.value;
|
||||
|
||||
var transmit_power_slider = document.getElementById("transmit_power_slider");
|
||||
var transmit_power_value = document.getElementById("transmit_power_value");
|
||||
transmit_power_value.innerHTML = transmit_power_slider.value;
|
||||
|
@ -94,10 +101,10 @@
|
|||
frequencies.forEach(freq => {
|
||||
const wavelength = 3e8 / (freq * 1e6);
|
||||
const l = (Math.PI * loop_diameter_slider.value) / wavelength;
|
||||
if (l <= 0.25) {
|
||||
//if (l <= 0.25) {
|
||||
const rr = (n_turns ** 2.0) * k * (l ** 4.0);
|
||||
retval.push({x:freq, y:rr});
|
||||
}
|
||||
//}
|
||||
});
|
||||
return retval;
|
||||
}
|
||||
|
@ -108,10 +115,10 @@
|
|||
frequencies.forEach(freq => {
|
||||
const wavelength = 3e8 / (freq * 1e6);
|
||||
const l = (Math.PI * loop_diameter_slider.value) / wavelength;
|
||||
if (l <= 0.25) {
|
||||
//if (l <= 0.25) {
|
||||
const reactance = 2.0 * Math.PI * (freq * 1e6) * inductance;
|
||||
retval.push({x:freq, y:reactance});
|
||||
}
|
||||
//}
|
||||
});
|
||||
return retval;
|
||||
}
|
||||
|
@ -122,20 +129,40 @@
|
|||
frequencies.forEach(freq => {
|
||||
const wavelength = 3e8 / (freq * 1e6);
|
||||
const l = (Math.PI * loop_diameter_slider.value) / wavelength;
|
||||
if (l <= 0.25) {
|
||||
//if (l <= 0.25) {
|
||||
const reactance = 2.0 * Math.PI * freq * 1e6 * inductance;
|
||||
const capacitor = 1e12 / (2.0 * Math.PI * freq * 1e6 * reactance);
|
||||
retval.push({x:freq, y:capacitor});
|
||||
}
|
||||
//}
|
||||
});
|
||||
return retval;
|
||||
}
|
||||
|
||||
function getProximityResFromSpacing(b_conductor_radius, c_loop_spacing) {
|
||||
const proximityResistance = {
|
||||
// From G. S. Smith, "Radiation Efficiency of Electrically Small Multiturn Loop Antennas", IEEE Trans Antennas Propagation, September 1972
|
||||
0:[ 1.1, 1.15, 1.20, 1.25, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.20, 2.40, 2.50, 2.60, 2.80, 3.00, 3.50, 4.00],
|
||||
1:[0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000],
|
||||
2:[0.299, 0.284, 0.268, 0.254, 0.240, 0.214, 0.191, 0.173, 0.155, 0.141, 0.128, 0.116, 0.098, 0.032, 0.077, 0.071, 0.061, 0.054, 0.040, 0.031],
|
||||
3:[0.643, 0.580, 0.531, 0.491, 0.455, 0.395, 0.346, 0.305, 0.270, 0.241, 0.216, 0.195, 0.161, 0.135, 0.124, 0.114, 0.098, 0.085, 0.062, 0.048],
|
||||
4:[0.996, 0.868, 0.777, 0.704, 0.644, 0.564, 0.470, 0.408, 0.353, 0.316, 0.281, 0.252, 0.205, 0.170, 0.156, 0.144, 0.123, 0.106, 0.077, 0.058],
|
||||
5:[1.347, 1.142, 1.002, 0.896, 0.809, 0.674, 0.572, 0.492, 0.428, 0.375, 0.332, 0.295, 0.239, 0.197, 0.180, 0.165, 0.141, 0.121, 0.087, 0.066],
|
||||
6:[1.689, 1.400, 1.210, 1.068, 0.956, 0.784, 0.658, 0.561, 0.485, 0.423, 0.372, 0.330, 0.265, 0.217, 0.198, 0.182, 0.154, 0.133, 0.095, 0.072],
|
||||
7:[2.020, 1.693, 1.401, 1.224, 1.086, 0.880, 0.732, 0.620, 0.532, 0.462, 0.405, 0.358, 0.286, 0.234, 0.213, 0.195, 0.165, 0.142, 0.101, 0.076],
|
||||
8:[2.340, 1.872, 1.577, 1.365, 1.203, 0.965, 0.796, 0.670, 0.573, 0.495, 0.433, 0.392, 0.304, 0.247, 0.225, 0.206, 0.174, 0.150, 0.106, 0.080]
|
||||
};
|
||||
|
||||
function getProximityResFromSpacing(spacing_ratio) {
|
||||
var retval = 0.0;
|
||||
const lut = { 1:[],
|
||||
2:[],
|
||||
const n_turns = loop_turns_slider.value;
|
||||
var i = 0;
|
||||
for (i = 0; i < (proximityResistance[0].length-1); i++) {
|
||||
if(spacing_ratio <= proximityResistance[0][i+1]) {
|
||||
// Linear interpolation between empirical proximity resistance values:
|
||||
retval = (((spacing_ratio - proximityResistance[0][i]) / (proximityResistance[0][i+1] - proximityResistance[0][i]) * (proximityResistance[n_turns][i+1] - proximityResistance[n_turns][i])) + proximityResistance[n_turns][i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
function calculateLossResistance() {
|
||||
|
@ -143,19 +170,39 @@
|
|||
const a_coil_radius = loop_diameter_slider.value * 0.5;
|
||||
const b_conductor_radius = conductor_diameter_slider.value * 0.0005;
|
||||
const n_turns = loop_turns_slider.value;
|
||||
const loop_spacing_ratio = loop_spacing_slider.value;
|
||||
const mu0 = 4.0 * Math.PI * 1e-7;
|
||||
const k = (n_turns * a_coil_radius / b_conductor_radius);
|
||||
const cu_sigma = 58e6;
|
||||
const Rp = getProximityResFromSpacing(loop_spacing_ratio);
|
||||
frequencies.forEach(freq => {
|
||||
const Rs = Math.sqrt(Math.PI * freq * 1e6 * mu0 / cu_sigma);
|
||||
// TODO *** finish this! Find eqn for Rp / R0;
|
||||
retval.push({x:freq, y:capacitor});
|
||||
const R0 = (n_turns * Rs) / (2.0 * Math.PI * b_conductor_radius);
|
||||
const R_ohmic = k * Rs * (Rp / R0 + 1.0);
|
||||
retval.push({x:freq, y:R_ohmic});
|
||||
});
|
||||
return retval;
|
||||
}
|
||||
|
||||
function calculateQualityFactor() {
|
||||
function calculateEfficiencyFactor() {
|
||||
const RL = calculateLossResistance();
|
||||
const RR = calculateRadiationResistance();
|
||||
var retval = [];
|
||||
for (let index = 0; index < RR.length; index++) {
|
||||
const Q = 1.0 / (1.0 + (RL[index].y / RR[index].y));
|
||||
retval.push({x:RL[index].x, y:Q});
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
function calculateQualityFactor() {
|
||||
const RL = calculateLossResistance();
|
||||
const RR = calculateRadiationResistance();
|
||||
var retval = [];
|
||||
for (let index = 0; index < RR.length; index++) {
|
||||
const Q = 1.0 / (1.0 + (RL[index].y / RR[index].y));
|
||||
retval.push({x:RL[index].x, y:Q});
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -164,6 +211,8 @@
|
|||
myChart.data.datasets[0].data = calculateRadiationResistance();
|
||||
myChart.data.datasets[1].data = calculateInductiveReactance();
|
||||
myChart.data.datasets[2].data = calculateTuningCapacitor();
|
||||
myChart.data.datasets[3].data = calculateLossResistance();
|
||||
myChart.data.datasets[4].data = calculateQualityFactor();
|
||||
myChart.update();
|
||||
}
|
||||
|
||||
|
@ -172,6 +221,8 @@
|
|||
myChart.data.datasets[0].data = calculateRadiationResistance();
|
||||
myChart.data.datasets[1].data = calculateInductiveReactance();
|
||||
// myChart.data.datasets[2].data = calculateTuningCapacitor();
|
||||
myChart.data.datasets[3].data = calculateLossResistance();
|
||||
myChart.data.datasets[4].data = calculateQualityFactor();
|
||||
myChart.update();
|
||||
}
|
||||
|
||||
|
@ -180,6 +231,18 @@
|
|||
myChart.data.datasets[0].data = calculateRadiationResistance();
|
||||
myChart.data.datasets[1].data = calculateInductiveReactance();
|
||||
myChart.data.datasets[2].data = calculateTuningCapacitor();
|
||||
myChart.data.datasets[3].data = calculateLossResistance();
|
||||
myChart.data.datasets[4].data = calculateQualityFactor();
|
||||
myChart.update();
|
||||
}
|
||||
|
||||
loop_spacing_slider.oninput = function() {
|
||||
loop_spacing_value.innerHTML = loop_spacing_slider.value;
|
||||
myChart.data.datasets[0].data = calculateRadiationResistance();
|
||||
myChart.data.datasets[1].data = calculateInductiveReactance();
|
||||
myChart.data.datasets[2].data = calculateTuningCapacitor();
|
||||
myChart.data.datasets[3].data = calculateLossResistance();
|
||||
myChart.data.datasets[4].data = calculateQualityFactor();
|
||||
myChart.update();
|
||||
}
|
||||
|
||||
|
@ -197,7 +260,8 @@
|
|||
var myChart = new Chart(chartCanvasContext, {
|
||||
type: 'line',
|
||||
data: {
|
||||
datasets: [{
|
||||
datasets: [
|
||||
{
|
||||
label: 'Radiation Resistance \u03A9',
|
||||
fill: false,
|
||||
borderColor: 'red',
|
||||
|
@ -223,6 +287,24 @@
|
|||
data: calculateTuningCapacitor(),
|
||||
borderWidth: 1,
|
||||
yAxisID: 'pfID'
|
||||
},
|
||||
{
|
||||
label: 'Loss Resistance \u03A9',
|
||||
fill: false,
|
||||
borderColor: 'orange',
|
||||
backgroundColor: 'orange',
|
||||
data: calculateLossResistance(),
|
||||
borderWidth: 1,
|
||||
yAxisID: 'mohmsID'
|
||||
},
|
||||
{
|
||||
label: 'Efficiency',
|
||||
fill: false,
|
||||
borderColor: 'black',
|
||||
backgroundColor: 'black',
|
||||
data: calculateQualityFactor(),
|
||||
borderWidth: 1,
|
||||
yAxisID: 'effID'
|
||||
}]
|
||||
},
|
||||
options: {
|
||||
|
@ -270,6 +352,17 @@
|
|||
},
|
||||
position: 'right',
|
||||
id: 'pfID'
|
||||
},{
|
||||
type: 'linear',
|
||||
display: true,
|
||||
scaleLabel: {
|
||||
display: true,
|
||||
labelString: 'Efficiency',
|
||||
fontColor: 'black',
|
||||
fontStyle: 'bold'
|
||||
},
|
||||
position: 'right',
|
||||
id: 'effID'
|
||||
}]
|
||||
},
|
||||
showLines: true
|
||||
|
|
Ładowanie…
Reference in New Issue