Files
50ohm-contents-dl/contents/html/applet_pm.html
T
SuperminarenandClaude Sonnet 5.5 f7fa8cfbc1 Swedish adaptation: Instegscertifikat and HAREC content
- 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>
2026-10-10 15:03:03 +02:00

159 lines
4.9 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<div class="container" style="max-width:860px;">
<div class="mb-2">
<div class="small text-secondary fw-semibold mb-1">Modulerande signal (meddelande)</div>
<canvas id="fmpm-c0" height="140" class="w-100 d-block rounded"></canvas>
</div>
<div class="mb-2">
<div class="small text-secondary fw-semibold mb-1">Bärvåg (omodulerad)</div>
<canvas id="fmpm-c1" height="70" class="w-100 d-block rounded"></canvas>
</div>
<div class="mb-2">
<div class="small text-secondary fw-semibold mb-1">FM – bärvågens frekvens följer signalvärdet</div>
<canvas id="fmpm-c2" height="70" class="w-100 d-block rounded"></canvas>
</div>
<div class="mb-3">
<div class="small text-secondary fw-semibold mb-1">PM – bärvågens fas följer signalvärdet direkt</div>
<canvas id="fmpm-c3" height="70" class="w-100 d-block rounded"></canvas>
</div>
<hr>
<div class="d-flex flex-column gap-3">
<div class="row align-items-center g-2">
<div class="col-auto" style="min-width:170px;">
<label class="col-form-label col-form-label-sm">Signalform</label>
</div>
<div class="col">
<select class="form-select form-select-sm" id="fmpm-shape">
<option value="sine">Sinus</option>
<option value="square">Fyrkant</option>
<option value="saw">Sågtand</option>
<option value="ramp">Linjär ramp</option>
</select>
</div>
</div>
</div>
</div>
<script>
(function () {
const IDS = ['fmpm-c0','fmpm-c1','fmpm-c2','fmpm-c3'];
const COLORS = ['#1D9E75','#888780','#378ADD','#D85A30'];
const N = 1200;
const FC = 8;
const DEPTH = 1.5;
function signal(shape, n) {
const t = n / N, fs = 1.2;
switch (shape) {
case 'sine': return Math.sin(2 * Math.PI * fs * t);
case 'square': return Math.sign(Math.sin(2 * Math.PI * fs * t));
case 'saw': return 2 * (fs * t % 1) - 1;
case 'ramp': return Math.max(-1, Math.min(1, 2 * t - 1));
default: return 0;
}
}
function draw() {
const depth = DEPTH;
const shape = document.getElementById('fmpm-shape').value;
const gridCount = 24;
const cvs = IDS.map(id => document.getElementById(id));
const dpr = window.devicePixelRatio || 1;
const w = cvs[0].offsetWidth || 800;
cvs.forEach(c => {
c.width = w * dpr;
c.height = c.offsetHeight * dpr;
});
let fmPhase = 0;
const pts = new Array(N);
for (let n = 0; n < N; n++) {
const t = n / N;
const sig = signal(shape, n);
const car = Math.sin(2 * Math.PI * FC * t);
fmPhase += 2 * Math.PI * (FC + depth * sig) / N;
const fm = Math.sin(fmPhase);
const pm = Math.sin(2 * Math.PI * FC * t + depth * sig);
pts[n] = { sig, car, fm, pm };
}
const zeros = [];
for (let n = 1; n < N; n++) {
if (pts[n-1].car <= 0 && pts[n].car > 0) zeros.push(n / N);
}
const series = [
pts.map(p => p.sig),
pts.map(p => p.car),
pts.map(p => p.fm),
pts.map(p => p.pm),
];
const gH = 'rgba(0,0,0,1)';
const gV = 'rgba(70,70,70,.5)';
const zV = 'rgba(120,120,120,0)';
series.forEach((data, i) => {
const c = cvs[i];
const ctx = c.getContext('2d');
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.scale(dpr, dpr);
const h = c.offsetHeight;
const mid = h / 2;
const amp = mid * 0.78;
ctx.strokeStyle = gH;
ctx.lineWidth = 0.9;
ctx.setLineDash([]);
ctx.beginPath(); ctx.moveTo(0, mid); ctx.lineTo(w, mid); ctx.stroke();
ctx.strokeStyle = gV;
ctx.lineWidth = 0.9;
ctx.setLineDash([4, 4]);
for (let g = 1; g < gridCount; g++) {
const x = (g / gridCount) * w;
ctx.beginPath(); ctx.moveTo(x, 0); ctx.lineTo(x, h); ctx.stroke();
}
if (i === 2 || i === 3) {
ctx.strokeStyle = zV;
ctx.lineWidth = 0.5;
ctx.setLineDash([2, 5]);
zeros.forEach(t => {
const x = t * w;
ctx.beginPath(); ctx.moveTo(x, 0); ctx.lineTo(x, h); ctx.stroke();
});
}
if (i === 1) {
ctx.setLineDash([]);
ctx.fillStyle = 'rgba(95,95,95,.60)';
zeros.forEach(t => {
ctx.beginPath();
ctx.arc(t * w, mid, 2.5, 0, 2 * Math.PI);
ctx.fill();
});
}
ctx.setLineDash([]);
ctx.strokeStyle = COLORS[i];
ctx.lineWidth = i === 0 ? 2 : 1.5;
ctx.lineJoin = 'round';
ctx.beginPath();
data.forEach((v, n) => {
const x = n / N * w;
const y = mid - v * amp;
n === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y);
});
ctx.stroke();
});
}
document.getElementById('fmpm-shape').addEventListener('change', draw);
new ResizeObserver(draw).observe(document.getElementById('fmpm-c0'));
draw();
})();
</script>