- Sections and slides rewritten in Swedish; German law and institutions replaced by Swedish/CEPT/ITU equivalents (PTS, SSA, PTSFS 2025:1, SSMFS 2008:18), unverified statements marked "% TODO VERIFY" - New toc: INSTEG, HAREC, UPPGRADERING; section idents are Swedish (see ident-map.tsv) - Exam-question tags, BNetzA question pool, solutions and the German SWL course removed - Static pages, snippets, applets, READMEs and image alt-texts translated - TikZ labels translated; SVG drawings regenerated (drawing 689 still fails to build upstream: it references a missing photo) - Changed from the original: not endorsed by DARC e.V., SSA or PTS Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
264 lines
12 KiB
HTML
264 lines
12 KiB
HTML
<html>
|
|
<div class="text-start" id="attenuator-calculator">
|
|
<p>Med den här appleten kan du beräkna symmetriska T- och pi-dämpsatser för ett 50-Ω-system.</p>
|
|
|
|
<div class="row g-3 align-items-end">
|
|
<div class="col-12 col-sm-6">
|
|
<label class="form-label" for="attenuator-db">Dämpning i dB</label>
|
|
<input class="form-control" id="attenuator-db" type="number" min="0.1" max="100" step="0.1" value="6" inputmode="decimal">
|
|
</div>
|
|
|
|
<div class="col-12 col-sm-6">
|
|
<label class="form-label" for="attenuator-impedance">Systemimpedans</label>
|
|
<input class="form-control" id="attenuator-impedance" type="text" value="50 Ω" readonly>
|
|
</div>
|
|
|
|
<div class="col-12 col-sm-6">
|
|
<span class="form-label d-block">Kopplingsform</span>
|
|
<div class="form-check form-check-inline">
|
|
<input class="form-check-input" id="attenuator-pi" type="radio" name="attenuator-topology" value="pi" checked>
|
|
<label class="form-check-label" for="attenuator-pi">Pi</label>
|
|
</div>
|
|
<div class="form-check form-check-inline">
|
|
<input class="form-check-input" id="attenuator-t" type="radio" name="attenuator-topology" value="t">
|
|
<label class="form-check-label" for="attenuator-t">T</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-12 col-sm-6">
|
|
<label class="form-label" for="attenuator-series">Standardserie</label>
|
|
<select class="form-select" id="attenuator-series">
|
|
<option value="E12">E12</option>
|
|
<option value="E24" selected>E24</option>
|
|
<option value="E48">E48</option>
|
|
<option value="E96">E96</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<p class="text-danger mt-3" id="attenuator-error" role="alert" hidden></p>
|
|
|
|
<div class="mt-4" id="attenuator-output">
|
|
<p class="mb-1">De ideala motståndsvärdena är:</p>
|
|
<div id="attenuator-ideal-result"></div>
|
|
|
|
<p class="mb-1">De närmaste motståndsvärdena ur <span id="attenuator-series-name">E24</span>-serien är:</p>
|
|
<div id="attenuator-standard-result"></div>
|
|
|
|
<p class="mb-1">Med dessa standardvärden uppnås följande dämpning:</p>
|
|
<div id="attenuator-achieved-result"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
(function() {
|
|
"use strict";
|
|
|
|
const impedance = 50;
|
|
const preferredValues = {
|
|
E12: [1.0, 1.2, 1.5, 1.8, 2.2, 2.7, 3.3, 3.9, 4.7, 5.6, 6.8, 8.2],
|
|
E24: [1.0, 1.1, 1.2, 1.3, 1.5, 1.6, 1.8, 2.0, 2.2, 2.4, 2.7, 3.0, 3.3, 3.6, 3.9, 4.3, 4.7, 5.1, 5.6, 6.2, 6.8, 7.5, 8.2, 9.1],
|
|
E48: [1.00, 1.05, 1.10, 1.15, 1.21, 1.27, 1.33, 1.40, 1.47, 1.54, 1.62, 1.69, 1.78, 1.87, 1.96, 2.05, 2.15, 2.26, 2.37, 2.49, 2.61, 2.74, 2.87, 3.01, 3.16, 3.32, 3.48, 3.65, 3.83, 4.02, 4.22, 4.42, 4.64, 4.87, 5.11, 5.36, 5.62, 5.90, 6.19, 6.49, 6.81, 7.15, 7.50, 7.87, 8.25, 8.66, 9.09, 9.53],
|
|
E96: [1.00, 1.02, 1.05, 1.07, 1.10, 1.13, 1.15, 1.18, 1.21, 1.24, 1.27, 1.30, 1.33, 1.37, 1.40, 1.43, 1.47, 1.50, 1.54, 1.58, 1.62, 1.65, 1.69, 1.74, 1.78, 1.82, 1.87, 1.91, 1.96, 2.00, 2.05, 2.10, 2.15, 2.21, 2.26, 2.32, 2.37, 2.43, 2.49, 2.55, 2.61, 2.67, 2.74, 2.80, 2.87, 2.94, 3.01, 3.09, 3.16, 3.24, 3.32, 3.40, 3.48, 3.57, 3.65, 3.74, 3.83, 3.92, 4.02, 4.12, 4.22, 4.32, 4.42, 4.53, 4.64, 4.75, 4.87, 4.99, 5.11, 5.23, 5.36, 5.49, 5.62, 5.76, 5.90, 6.04, 6.19, 6.34, 6.49, 6.65, 6.81, 6.98, 7.15, 7.32, 7.50, 7.68, 7.87, 8.06, 8.25, 8.45, 8.66, 8.87, 9.09, 9.31, 9.53, 9.76]
|
|
};
|
|
|
|
const attenuationInput = document.getElementById("attenuator-db");
|
|
const seriesSelect = document.getElementById("attenuator-series");
|
|
const output = document.getElementById("attenuator-output");
|
|
const error = document.getElementById("attenuator-error");
|
|
const idealResult = document.getElementById("attenuator-ideal-result");
|
|
const standardResult = document.getElementById("attenuator-standard-result");
|
|
const achievedResult = document.getElementById("attenuator-achieved-result");
|
|
const latexResults = [idealResult, standardResult, achievedResult];
|
|
let katexWaitTimer = null;
|
|
|
|
function decimalLatex(value, maximumFractionDigits, minimumFractionDigits = 0) {
|
|
return value.toLocaleString("sv-SE", {
|
|
maximumFractionDigits: maximumFractionDigits,
|
|
minimumFractionDigits: minimumFractionDigits,
|
|
useGrouping: false
|
|
}).replace(",", "{,}");
|
|
}
|
|
|
|
function resistanceLatex(value) {
|
|
if (value >= 1e6) {
|
|
return decimalLatex(value / 1e6, 3) + "\\,\\mathrm{M}\\Omega";
|
|
}
|
|
if (value >= 1e3) {
|
|
return decimalLatex(value / 1e3, 3) + "\\,\\mathrm{k}\\Omega";
|
|
}
|
|
return decimalLatex(value, 2) + "\\,\\Omega";
|
|
}
|
|
|
|
function nearestPreferredValue(value, seriesName) {
|
|
const values = preferredValues[seriesName];
|
|
const decade = Math.floor(Math.log10(value));
|
|
const candidates = [];
|
|
|
|
for (let exponent = decade - 1; exponent <= decade + 1; exponent += 1) {
|
|
values.forEach(function(baseValue) {
|
|
candidates.push(baseValue * Math.pow(10, exponent));
|
|
});
|
|
}
|
|
|
|
return candidates.reduce(function(nearest, candidate) {
|
|
return Math.abs(candidate - value) < Math.abs(nearest - value) ? candidate : nearest;
|
|
});
|
|
}
|
|
|
|
function multiplyMatrices(left, right) {
|
|
return [
|
|
[
|
|
left[0][0] * right[0][0] + left[0][1] * right[1][0],
|
|
left[0][0] * right[0][1] + left[0][1] * right[1][1]
|
|
],
|
|
[
|
|
left[1][0] * right[0][0] + left[1][1] * right[1][0],
|
|
left[1][0] * right[0][1] + left[1][1] * right[1][1]
|
|
]
|
|
];
|
|
}
|
|
|
|
function achievedAttenuation(topology, symmetricResistance, middleResistance) {
|
|
const seriesMatrix = function(resistance) {
|
|
return [[1, resistance], [0, 1]];
|
|
};
|
|
const shuntMatrix = function(resistance) {
|
|
return [[1, 0], [1 / resistance, 1]];
|
|
};
|
|
let matrix;
|
|
|
|
if (topology === "pi") {
|
|
matrix = multiplyMatrices(
|
|
multiplyMatrices(shuntMatrix(symmetricResistance), seriesMatrix(middleResistance)),
|
|
shuntMatrix(symmetricResistance)
|
|
);
|
|
} else {
|
|
matrix = multiplyMatrices(
|
|
multiplyMatrices(seriesMatrix(symmetricResistance), shuntMatrix(middleResistance)),
|
|
seriesMatrix(symmetricResistance)
|
|
);
|
|
}
|
|
|
|
const denominator = matrix[0][0]
|
|
+ matrix[0][1] / impedance
|
|
+ matrix[1][0] * impedance
|
|
+ matrix[1][1];
|
|
const transmission = 2 / denominator;
|
|
return -20 * Math.log10(Math.abs(transmission));
|
|
}
|
|
|
|
function katexIsReady() {
|
|
return window.katex && typeof window.katex.render === "function";
|
|
}
|
|
|
|
function setLatex(element, latex) {
|
|
element.attenuatorLatex = latex;
|
|
|
|
if (katexIsReady()) {
|
|
window.katex.render(latex, element, {
|
|
displayMode: true,
|
|
throwOnError: false,
|
|
strict: false
|
|
});
|
|
return;
|
|
}
|
|
|
|
element.textContent = "";
|
|
}
|
|
|
|
function renderResultsWhenKatexIsReady() {
|
|
if (katexIsReady()) {
|
|
katexWaitTimer = null;
|
|
latexResults.forEach(function(element) {
|
|
setLatex(element, element.attenuatorLatex);
|
|
});
|
|
return;
|
|
}
|
|
|
|
if (katexWaitTimer === null) {
|
|
katexWaitTimer = window.setTimeout(function() {
|
|
katexWaitTimer = null;
|
|
renderResultsWhenKatexIsReady();
|
|
}, 50);
|
|
}
|
|
}
|
|
|
|
function networkValuesLatex(topology, symmetricResistance, middleResistance) {
|
|
if (topology === "pi") {
|
|
return "\\begin{aligned}"
|
|
+ "R_1=R_3&=" + resistanceLatex(symmetricResistance) + "\\\\"
|
|
+ "R_2&=" + resistanceLatex(middleResistance)
|
|
+ "\\end{aligned}";
|
|
}
|
|
|
|
return "\\begin{aligned}"
|
|
+ "R_1=R_2&=" + resistanceLatex(symmetricResistance) + "\\\\"
|
|
+ "R_3&=" + resistanceLatex(middleResistance)
|
|
+ "\\end{aligned}";
|
|
}
|
|
|
|
function calculate() {
|
|
const attenuation = attenuationInput.valueAsNumber;
|
|
const topology = document.querySelector('input[name="attenuator-topology"]:checked').value;
|
|
const seriesName = seriesSelect.value;
|
|
|
|
if (!Number.isFinite(attenuation) || attenuation <= 0 || attenuation > 100) {
|
|
error.textContent = "Ange en dämpning mellan 0,1 dB och 100 dB.";
|
|
error.hidden = false;
|
|
output.hidden = true;
|
|
return;
|
|
}
|
|
|
|
error.hidden = true;
|
|
output.hidden = false;
|
|
|
|
const voltageRatio = Math.pow(10, attenuation / 20);
|
|
let symmetricResistance;
|
|
let middleResistance;
|
|
|
|
if (topology === "pi") {
|
|
symmetricResistance = impedance * (voltageRatio + 1) / (voltageRatio - 1);
|
|
middleResistance = impedance * (voltageRatio * voltageRatio - 1) / (2 * voltageRatio);
|
|
} else {
|
|
symmetricResistance = impedance * (voltageRatio - 1) / (voltageRatio + 1);
|
|
middleResistance = 2 * impedance * voltageRatio / (voltageRatio * voltageRatio - 1);
|
|
}
|
|
|
|
const preferredSymmetricResistance = nearestPreferredValue(symmetricResistance, seriesName);
|
|
const preferredMiddleResistance = nearestPreferredValue(middleResistance, seriesName);
|
|
const actualAttenuation = achievedAttenuation(
|
|
topology,
|
|
preferredSymmetricResistance,
|
|
preferredMiddleResistance
|
|
);
|
|
|
|
setLatex(
|
|
idealResult,
|
|
networkValuesLatex(topology, symmetricResistance, middleResistance)
|
|
);
|
|
setLatex(
|
|
standardResult,
|
|
networkValuesLatex(topology, preferredSymmetricResistance, preferredMiddleResistance)
|
|
);
|
|
setLatex(
|
|
achievedResult,
|
|
"a_\\mathrm{erreicht}=" + decimalLatex(actualAttenuation, 2, 2) + "\\,\\mathrm{dB}"
|
|
);
|
|
document.getElementById("attenuator-series-name").textContent = seriesName;
|
|
if (!katexIsReady()) {
|
|
renderResultsWhenKatexIsReady();
|
|
}
|
|
}
|
|
|
|
attenuationInput.addEventListener("input", calculate);
|
|
seriesSelect.addEventListener("change", calculate);
|
|
document.querySelectorAll('input[name="attenuator-topology"]').forEach(function(input) {
|
|
input.addEventListener("change", calculate);
|
|
});
|
|
|
|
calculate();
|
|
}());
|
|
</script>
|
|
</html>
|