Merge pull request #161 from DARC-e-V/feature/pm-applet
Feature/pm applet
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
<div class="container" style="max-width:860px;">
|
||||
<div class="mb-2">
|
||||
<div class="small text-secondary fw-semibold mb-1">Modulierendes Signal (Nachricht)</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">Trägersignal (unmoduliert)</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 – Frequenz des Trägers folgt dem Signal-Wert</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 – Phase des Trägers folgt dem Signal-Wert 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">Rechteck</option>
|
||||
<option value="saw">Sägezahn</option>
|
||||
<option value="ramp">Linearer Anstieg</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>
|
||||
+34
-6
@@ -1,15 +1,43 @@
|
||||
Bei der Phasenmodulation wird die Phase einer Trägerwelle in Abhängigkeit vom Modulationssignal verändert. Das bedeutet, dass die Phasenverschiebung der Trägerwelle direkt proportional zur Amplitude des Modulationssignals variiert. Diese Veränderung der Phase bleibt im Verlauf des Signals erhalten und variiert im Vergleich zur ursprünglichen Trägerwelle in einem bestimmten Muster. Das Resultat ist ein sinusförmiges Signal, dessen „Versatz“ (Phase) sich laufend anpasst, ohne dass sich dabei die Amplitude des Signals ändert.
|
||||
|
||||
Die Phasenmodulation kann man sich bildlich als das Verschieben der Sinuskurve entlang der Zeitachse vorstellen, wobei jede Veränderung der Phase durch das Modulationssignal gesteuert wird. Je stärker die Amplitude des Modulationssignals, desto mehr verschiebt sich die Phase des Trägersignals. Dabei bleibt die Frequenz des Signals grundsätzlich konstant.
|
||||
Die Phasenmodulation kann man sich bildlich als das Verschieben der Sinuskurve entlang der Zeitachse vorstellen, wobei jede Veränderung der Phase durch das Modulationssignal gesteuert wird. Je stärker die Amplitude des Modulationssignals, desto mehr verschiebt sich die Phase des Trägersignals.
|
||||
|
||||
[picture:907:a_phasenmodulation:Phasenmodulation mit Umkehrung der Phase]
|
||||
|
||||
<indepth>
|
||||
Phasenmodulation und Frequenzmodulation gehören beide zur Gruppe der Winkelmodulationstechniken, da sie beide den Winkel der Trägerwelle beeinflussen. Der Unterschied liegt darin, dass bei der Frequenzmodulation die Frequenz und bei der Phasenmodulation die Phase direkt beeinflusst wird.
|
||||
|
||||
Die beiden Modulationsarten stehen in einem engen Zusammenhang: Die Phasenmodulation eines Signals hat indirekt eine Veränderung der Frequenz zur Folge, und umgekehrt erzeugt die Frequenzmodulation eine Änderung der Phase. Da Frequenzänderungen letztlich auch eine Änderung der Phase bewirken, kann man Frequenzmodulation durch ein PM-System simulieren.
|
||||
Dies zeigt sich besonders deutlich bei einem Rechtecksignal als Nutzsignal: Bei der Phasenmodulation bewirkt jede Flanke des Rechtecks einen sofortigen Phasensprung des Trägersignals, während bei der Frequenzmodulation die Signalflanke lediglich einen Frequenzwechsel auslöst – die daraus resultierende Phasenänderung entsteht erst indirekt, indem sie sich kontinuierlich über die Zeit aufakkumuliert.
|
||||
|
||||
In technischen Systemen ist es oft möglich, FM durch PM zu realisieren, indem das Modulationssignal integriert wird. Da die Frequenzänderung die Ableitung der Phase ist, entspricht die Integration des Modulationssignals einer schrittweisen Anpassung der Phase, was die gleiche Wirkung wie Frequenzmodulation erzielt.
|
||||
<margin>
|
||||
[picture:907:a_phasenmodulation:Phasenmodulation mit Umkehrung der Phase]
|
||||
</margin>
|
||||
|
||||
<webonly>
|
||||
<margin>
|
||||
[include:applet_pm]
|
||||
</margin>
|
||||
</webonly>
|
||||
|
||||
<indepth>
|
||||
Für mathematisch Interessierte: Bei der Phasenmodulation hat das Nutzsignal $m(t)$ einen direkten Einfluss auf die Phase, z. B.:
|
||||
|
||||
$\varphi(t) = m(t)$
|
||||
|
||||
Das Trägersignal wird als Sinusschwingung der Form
|
||||
|
||||
$s(t) = A_c \cos(2\pi f_c t + \varphi(t))$
|
||||
|
||||
erzeugt, wobei $A_c$ die Amplitude, $f_c$ die Trägerfrequenz und $\varphi(t)$ die modulierte Phase ist.
|
||||
|
||||
Die beiden Modulationsarten FM und PM stehen in einem engen Zusammenhang: Die Phasenmodulation eines Signals hat indirekt eine Veränderung der Frequenz zur Folge, und umgekehrt erzeugt die Frequenzmodulation eine Änderung der Phase. Mathematisch kann man den Zusammenhang zwischen Frequenz und Phase durch die folgende Beziehung ausdrücken:
|
||||
|
||||
$f_i(t) = \frac{1}{2\pi} \cdot \frac{d\varphi(t)}{dt}$
|
||||
|
||||
Das bedeutet die Frequenz ist die zeitliche Ableitung der Phase.
|
||||
|
||||
Es ist also möglich, die Frequenzmodulation durch Phasenmodulation zu realisieren, indem das Nutzsignal $m(t)$ integriert wird:
|
||||
|
||||
$\varphi(t) = 2\pi \int m(t) \, dt$
|
||||
|
||||
Das Ergebnis wird anschließend als $\varphi(t)$ in die Trägerfunktion eingesetzt.
|
||||
</indepth>
|
||||
|
||||
[question:AE313]
|
||||
Reference in New Issue
Block a user