# Transducer <!-- MICROSIMGEN:BEGIN v1.7 — generated by g08_place_microsims.py; three.js first (§15); do not hand-edit inside --> ## Microsims — p5.js ### Transducer (p5.js) · `energy convert` <div class="microsim-player"> <iframe src="https://editor.p5js.org/sciencenibber/full/kMi3GOmq5" width="100%" height="480" frameborder="0" loading="lazy" sandbox="allow-scripts allow-same-origin" title="Transducer — p5.js microsim"></iframe> </div> *Any device that turns one form of energy into another — microphone, speaker, antenna, sensor.* **Open in the editor:** [&#9654; fork this sketch](https://editor.p5js.org/sciencenibber/sketches/kMi3GOmq5) · movement *VIII · Imaging, audio & sensors* · library `p5js` ### Related microsims Live sims on neighbouring articles — 1 of them inside this article's own Wikipedia link tree: - [[Sensor]] *(in tree)* - [[Decibel]] - [[Digital_image_processing]] - [[Distortion]] - [[Magnetic_resonance_imaging]] - [[Analog_signal]] *Sim hosted off-article; the article owns the reference, not the runtime (WIKI_RULES §10.4). Placed by `g08_place_microsims.py`.* <!-- g09-shelf-note --> > **Also on this page:** 1 further p5.js sketch already published for this article live further down. Per WIKI_RULES §5 a collision promotes rather than forks — they are one shelf, not rivals; this block is the §10.4 *current best* reference. <!-- MICROSIMGEN:END --> ## Microsim <iframe src="https://editor.p5js.org/sciencenibber/full/Cb_IFki6B" width="100%" height="620" frameborder="0" sandbox="allow-scripts allow-same-origin"></iframe> <img src="../SPINTRONICS Images/Transducer.png" alt="Transducer microsim"> *Live sketch: [open in the p5.js editor](https://editor.p5js.org/sciencenibber/sketches/Cb_IFki6B). The poster image above is a placeholder pending an attended or server-side canvas capture.* ### p5.js source ```js // ===================================================================== // Transducer - Wikitube MicroSim (SPINTRONICS hub, branch T - Transducers) // Slug/ARTICLE: "Transducer" -> en.wikitube.io/wiki/Transducer // --------------------------------------------------------------------- // CONCEPT // A transducer converts a measurand x(t) into an electrical output V(t). // Four characteristics - the same four used to RATE real transducers - // decide how faithfully it does so, and each is a control here: // * Sensitivity S : slope of the transfer characteristic V = S*x // * Range/sat. Vsat : output saturates (clips) at +/-Vsat // * Bandwidth fc : first-order roll-off; gain G(f) and lag phi(f) // * Noise floor sigma: RMS additive output noise; sets dynamic range // // MODEL (steady-state sinusoidal / frequency-response view) // x(t) = A*sin(2*pi*f*t) // G(f) = 1/sqrt(1 + (f/fc)^2) // amplitude gain (<= 1) // phi(f) = -atan(f/fc) // phase lag (rad) // V(t) = clamp( S*A*G*sin(2*pi*f*t + phi), -Vsat, +Vsat ) + noise(sigma) // The dynamic operating point (x(t), V(t)) traces a Lissajous loop that // opens from a line into a lagging ellipse as f -> fc (= visible bandwidth). // // A-V PATTERN: composition - a G block-diagram strip (measurand -> transducer // -> output) over a quantitative transfer-characteristic chart (left) and an // H signals-over-time scrolling-scope pair of traces (right). // // GOLDEN-RULES COMPLIANCE // * createCanvas(720,520) + pixelDensity(2); layout from width/height. // * Controls use real symbols + meaningful ranges; Reset restores ALL state. // * HUD watermark drawn last: title | URL | hints | live equation footer. // * ASCII only in every string/text(); Unicode (pi, sigma, phi) only in comments. // * Frame-rate independent: dt = min(deltaTime/1000, 0.05). The model is // closed-form (not an energy-conserving ODE) -> velocity-Verlet is N/A. // * Default noLoop()+redraw() (input-driven); Run toggles a LIGHT loop(). // Per-frame work = a few hundred polyline vertices; static scaffolding is // baked once into an offscreen buffer; setup() is cheap. No per-pixel / // per-atom inner loops -> does not trip the editor loop-protect. // * p5.disableFriendlyErrors = true; no allocation inside draw(). // ===================================================================== p5.disableFriendlyErrors = true; // quiet the FES (perf + clean console) const ARTICLE = "Transducer"; // single source of truth (HUD/URL/save) const WIKI = "en.wikitube.io/wiki/Transducer"; // ---- fixed axis full-scales (kept constant so readouts don't rescale) ------- const AXMAX = 10; // input axis: x in [-10, +10] units const VAXMAX = 400; // output axis: V in [-400, +400] mV // ---- layout (all derived from the 720x520 canvas; no magic coords in draw) -- const FOOTY = 326; // y where the live-equation footer sits const PTOP = 84; // panels top // left panel (transfer characteristic) const LX0 = 52, LX1 = 348, LY0 = PTOP, LY1 = 322; // right panel (time traces) split into input (top) + output (bottom) const RX0 = 396, RX1 = 704; const RIN0 = PTOP, RIN1 = 198; // input sub-panel y-range const ROUT0 = 208, ROUT1 = 322; // output sub-panel y-range // ---- control defaults (also used by Reset) ---------------------------------- const DEF = { S: 20, A: 7, f: 2, fc: 6, Vsat: 200, sig: 0 }; // ---- DOM controls ----------------------------------------------------------- let sldS, sldA, sldF, sldFc, sldVsat, sldSig; // six sliders let btnRun, btnReset; // two buttons // ---- animation state -------------------------------------------------------- let running = false; // paused by default (noLoop) let tsec = 0; // elapsed model time (s), advanced by dt // ---- baked static scenery --------------------------------------------------- let scene; // p5.Graphics drawn once in setup() // ===================================================================== // setup // ===================================================================== function setup() { createCanvas(720, 520); pixelDensity(2); textFont("Helvetica"); // -- sliders: (min, max, value, step) then .position(pageX,pageY).size(w) --- // the canvas sits at page (0,0) so page coords line up with canvas coords. const w = 130; sldS = createSlider(5, 60, DEF.S, 1); sldS.position(120, 378); sldS.size(w); sldA = createSlider(0, 10, DEF.A, 0.1); sldA.position(120, 416); sldA.size(w); sldF = createSlider(0.2, 20, DEF.f, 0.1); sldF.position(120, 454); sldF.size(w); sldFc = createSlider(0.5, 20, DEF.fc, 0.1); sldFc.position(476, 378); sldFc.size(w); sldVsat = createSlider(50, 400, DEF.Vsat, 5); sldVsat.position(476, 416); sldVsat.size(w); sldSig = createSlider(0, 20, DEF.sig, 0.5); sldSig.position(476, 454); sldSig.size(w); // redraw on any slider change so the PAUSED view updates live while dragging for (const s of [sldS, sldA, sldF, sldFc, sldVsat, sldSig]) s.input(redraw); // -- buttons -------------------------------------------------------------- btnRun = createButton("Run"); btnRun.position(120, 490); btnRun.size(80, 22); btnRun.mousePressed(toggleRun); btnReset = createButton("Reset"); btnReset.position(210, 490); btnReset.size(80, 22); btnReset.mousePressed(resetAll); buildScene(); // bake panels, axes, ticks, block diagram ONCE noLoop(); // input-driven by default; Run switches to loop() } // ===================================================================== // buildScene - bake everything static into the offscreen buffer once // ===================================================================== function buildScene() { scene = createGraphics(720, 520); const g = scene; g.pixelDensity(2); g.background("#0f1420"); g.textFont("Helvetica"); // ---- header caption + block diagram: measurand -> TRANSDUCER -> output ---- g.noStroke(); g.fill("#7f8aa3"); g.textSize(9); g.textAlign(CENTER, TOP); g.text("sensor: x -> V actuator: V -> x (reciprocal)", 360, 6); g.textAlign(CENTER, CENTER); drawBox(g, 18, 30, 150, 34, "#16203a", "#3d5a9a"); g.fill("#cfe0ff"); g.textSize(11); g.text("measurand x(t)", 18 + 75, 30 + 17); drawBox(g, 285, 26, 170, 42, "#1d2a17", "#5a8a3d"); g.fill("#dfffcf"); g.textSize(12); g.text("TRANSDUCER", 285 + 85, 26 + 13); g.textSize(10); g.fill("#bfe6a8"); g.text("V = S * x (clamped)", 285 + 85, 26 + 30); drawBox(g, 552, 30, 150, 34, "#2a1717", "#9a5a5a"); g.fill("#ffd9d9"); g.textSize(11); g.text("output V(t)", 552 + 75, 30 + 17); arrow(g, 168, 47, 285, 47); // x -> transducer arrow(g, 455, 47, 552, 47); // transducer -> V // ---- LEFT panel: transfer characteristic V(x) ---- panelFrame(g, LX0, LY0, LX1, LY1, "transfer characteristic V vs x"); const cx = mapX(0), cyz = mapY(0); // zero axes inside left panel g.stroke("#2b3550"); g.strokeWeight(1); g.line(LX0 + 1, cyz, LX1 - 1, cyz); // V = 0 horizontal axis g.line(cx, LY0 + 14, cx, LY1 - 1); // x = 0 vertical axis // x ticks (units) g.textSize(8); g.fill("#7f8aa3"); g.textAlign(CENTER, TOP); for (let xv = -10; xv <= 10; xv += 5) { const px = mapX(xv); g.stroke("#243049"); g.line(px, cyz - 3, px, cyz + 3); g.noStroke(); if (xv !== 0) g.text(xv, px, cyz + 4); } // V ticks (mV) g.textAlign(RIGHT, CENTER); for (let vv = -400; vv <= 400; vv += 200) { const py = mapY(vv); g.stroke("#243049"); g.line(cx - 3, py, cx + 3, py); g.noStroke(); if (vv !== 0) g.text(vv, cx - 6, py); } g.fill("#9aa6c2"); g.textSize(9); g.textAlign(LEFT, BOTTOM); g.text("x (units)", LX1 - 58, LY1 - 4); g.textAlign(LEFT, TOP); g.text("V (mV)", LX0 + 5, LY0 + 16); // ---- RIGHT panel: input + output trace sub-panels ---- panelFrame(g, RX0, RIN0, RX1, RIN1, "input x(t)"); panelFrame(g, RX0, ROUT0, RX1, ROUT1, "output V(t)"); g.stroke("#2b3550"); // zero line in each sub-panel g.line(RX0 + 1, (RIN0 + RIN1) / 2, RX1 - 1, (RIN0 + RIN1) / 2); g.line(RX0 + 1, (ROUT0 + ROUT1) / 2, RX1 - 1, (ROUT0 + ROUT1) / 2); g.noStroke(); g.fill("#9aa6c2"); g.textSize(9); g.textAlign(RIGHT, BOTTOM); g.text("t (window = 3 periods, scrolling)", RX1 - 4, ROUT1 - 3); } // small helper: filled+stroked rounded box (baked use only) function drawBox(g, x, y, w, h, fillc, strokec) { g.stroke(strokec); g.strokeWeight(1.5); g.fill(fillc); g.rect(x, y, w, h, 6); } // small helper: arrow with a head (baked use only) function arrow(g, x1, y1, x2, y2) { g.stroke("#6f7ea8"); g.strokeWeight(2); g.line(x1, y1, x2, y2); g.noStroke(); g.fill("#6f7ea8"); g.triangle(x2, y2, x2 - 8, y2 - 4, x2 - 8, y2 + 4); } // small helper: panel frame + caption function panelFrame(g, x0, y0, x1, y1, label) { g.noFill(); g.stroke("#33405f"); g.strokeWeight(1.2); g.rect(x0, y0, x1 - x0, y1 - y0, 4); g.noStroke(); g.fill("#aebbd9"); g.textSize(10); g.textAlign(LEFT, TOP); g.text(label, x0 + 6, y0 + 3); } // ===================================================================== // coordinate maps (use p5 map(); these names do NOT shadow p5's map) // ===================================================================== function mapX(x) { return map(x, -AXMAX, AXMAX, LX0 + 8, LX1 - 6); } // left x-axis function mapY(v) { return map(v, -VAXMAX, VAXMAX, LY1 - 6, LY0 + 16); } // left V-axis function mapInY(x) { return map(x, -AXMAX, AXMAX, RIN1 - 6, RIN0 + 16); } // input trace function mapOutY(v) { return map(v, -VAXMAX, VAXMAX, ROUT1 - 6, ROUT0 + 16); } // output trace function mapT(t, t0, win) { return map(t, t0, t0 + win, RX0 + 6, RX1 - 6); } // scrolling time // cheap deterministic gaussian (Box-Muller) via p5 random() -> obeys randomSeed function gaussv() { return sqrt(-2 * log(random() + 1e-9)) * cos(TWO_PI * random()); } // dynamic output for an input phase ph (clamped, pre-noise) function outAt(ph, A, S, G, phi, Vsat) { return constrain(S * A * G * sin(ph + phi), -Vsat, Vsat); } // ===================================================================== // draw // ===================================================================== function draw() { // -- read every control ONCE into named locals ----------------------------- const S = sldS.value(); // mV per unit (sensitivity = slope) const A = sldA.value(); // units (input half-span) const f = sldF.value(); // Hz (drive frequency) const fc = sldFc.value(); // Hz (-3 dB bandwidth) const Vsat = sldVsat.value(); // mV (saturation / range) const sig = sldSig.value(); // mV (RMS noise floor) // -- derived frequency-response quantities --------------------------------- const G = 1 / sqrt(1 + (f / fc) * (f / fc)); // amplitude gain <= 1 const phi = -atan(f / fc); // phase lag (rad) const peak = S * A * G; // ideal output peak (mV) // -- advance model time only while running (frame-rate independent) --------- if (running) { const dt = min(deltaTime / 1000, 0.05); // clamp big frame gaps tsec += dt; if (tsec > 1e6) tsec = 0; // guard against unbounded growth } image(scene, 0, 0); // blit baked panels/axes/diagram drawTransfer(S, A, f, G, phi, Vsat, sig); drawTraces(S, A, f, G, phi, Vsat, sig); drawHUD(S, A, f, fc, Vsat, sig, G, phi, peak); } // --------------------------------------------------------------------- // LEFT panel: static characteristic line + dynamic Lissajous operating loop // --------------------------------------------------------------------- function drawTransfer(S, A, f, G, phi, Vsat, sig) { // noise band: +/- sigma around the ideal characteristic (faint fill) if (sig > 0) { noStroke(); fill(120, 150, 220, 40); beginShape(); for (let xv = -AXMAX; xv <= AXMAX; xv += 1) vertex(mapX(xv), mapY(constrain(S * xv, -Vsat, Vsat) + sig)); for (let xv = AXMAX; xv >= -AXMAX; xv -= 1) vertex(mapX(xv), mapY(constrain(S * xv, -Vsat, Vsat) - sig)); endShape(CLOSE); } // static transfer characteristic V = clamp(S*x): sloped line + flat plateaus stroke("#7fe08a"); strokeWeight(2.5); noFill(); beginShape(); for (let xv = -AXMAX; xv <= AXMAX; xv += 0.5) vertex(mapX(xv), mapY(constrain(S * xv, -Vsat, Vsat))); endShape(); // highlight the saturation plateaus in red where the line has flattened const xSat = Vsat / S; // |x| beyond which output clips if (xSat < AXMAX) { stroke("#ff6b6b"); strokeWeight(2.5); line(mapX(xSat), mapY(Vsat), mapX(AXMAX), mapY(Vsat)); line(mapX(-xSat), mapY(-Vsat), mapX(-AXMAX), mapY(-Vsat)); } // dynamic operating loop: one period back from the current phase. // f<<fc -> collapses onto the line; near/above fc -> opens to a lagging ellipse. const ph0 = TWO_PI * f * tsec; const NT = 72; stroke(255, 210, 120, 150); strokeWeight(1.5); noFill(); beginShape(); for (let k = 0; k <= NT; k++) { const ph = ph0 - TWO_PI * (k / NT); vertex(mapX(A * sin(ph)), mapY(outAt(ph, A, S, G, phi, Vsat))); } endShape(); // current operating point (with a noisy output sample) randomSeed(running ? floor(frameCount / 2) : 7); const xNow = A * sin(ph0); const vNow = outAt(ph0, A, S, G, phi, Vsat) + sig * gaussv(); const px = mapX(xNow), py = mapY(constrain(vNow, -VAXMAX, VAXMAX)); stroke(150, 165, 200, 120); strokeWeight(1); // guide lines to the axes line(px, mapY(0), px, py); line(mapX(0), py, px, py); noStroke(); fill("#ffffff"); circle(px, py, 8); // slope annotation (sensitivity) noStroke(); fill("#7fe08a"); textSize(10); textAlign(LEFT, BOTTOM); text("slope = S", mapX(AXMAX) - 70, mapY(constrain(S * AXMAX, -Vsat, Vsat)) - 4); } // --------------------------------------------------------------------- // RIGHT panel: scrolling input (top) + output (bottom), newest at right edge // --------------------------------------------------------------------- function drawTraces(S, A, f, G, phi, Vsat, sig) { const Twin = 3 / f; // window = 3 periods regardless of f const t0 = tsec - Twin; // window start (newest sample at tsec) const N = 300; // light sample count across the panel // input x(t) (cyan) stroke("#5fd0ff"); strokeWeight(2); noFill(); beginShape(); for (let i = 0; i <= N; i++) { const t = t0 + (i / N) * Twin; vertex(mapT(t, t0, Twin), mapInY(A * sin(TWO_PI * f * t))); } endShape(); // output V(t) (amber): clamped, lagged, noisy. Seed for a stable paused frame. randomSeed(running ? floor(frameCount / 2) + 1 : 11); stroke("#ffb347"); strokeWeight(2); noFill(); beginShape(); for (let i = 0; i <= N; i++) { const t = t0 + (i / N) * Twin; const v = constrain(S * A * G * sin(TWO_PI * f * t + phi), -Vsat, Vsat) + sig * gaussv(); vertex(mapT(t, t0, Twin), mapOutY(constrain(v, -VAXMAX, VAXMAX))); } endShape(); // dashed saturation guides on the output sub-panel when peaks would clip if (S * A * G > Vsat) { stroke(255, 107, 107, 130); strokeWeight(1); drawingContext.setLineDash([4, 4]); line(RX0 + 6, mapOutY(Vsat), RX1 - 6, mapOutY(Vsat)); line(RX0 + 6, mapOutY(-Vsat), RX1 - 6, mapOutY(-Vsat)); drawingContext.setLineDash([]); } // "now" marker at the right edge of both sub-panels (newest sample) const xEnd = A * sin(TWO_PI * f * tsec); const vEnd = constrain(S * A * G * sin(TWO_PI * f * tsec + phi), -Vsat, Vsat); noStroke(); fill("#5fd0ff"); circle(RX1 - 6, mapInY(xEnd), 6); fill("#ffb347"); circle(RX1 - 6, mapOutY(vEnd), 6); } // --------------------------------------------------------------------- // HUD watermark (drawn LAST): title | URL | hints | live equation footer // + the six control labels/values + a 3-mode status flag. // --------------------------------------------------------------------- function drawHUD(S, A, f, fc, Vsat, sig, G, phi, peak) { // ---- control labels + live values (next to each slider) ---- noStroke(); textSize(11); fill("#cfe0ff"); textAlign(LEFT, CENTER); text("S", 14, 389); text("A", 14, 427); text("f", 14, 465); text("fc", 372, 389); text("Vsat", 372, 427); text("sigma", 372, 465); fill("#9fe6b0"); text(nf(S, 0, 0) + " mV/u", 256, 389); text(nf(A, 0, 1) + " u", 256, 427); text(nf(f, 0, 1) + " Hz", 256, 465); text(nf(fc, 0, 1) + " Hz", 612, 389); text(nf(Vsat, 0, 0) + " mV", 612, 427); text(nf(sig, 0, 1) + " mV", 612, 465); // ---- HUD part 1: title (top-left) ---- fill("#ffffff"); textSize(13); textAlign(LEFT, TOP); text("Transducer - input measurand to electrical output", 12, 8); // ---- HUD part 2: URL (top-right) ---- fill("#8fa0c8"); textSize(10); textAlign(RIGHT, TOP); text(WIKI, 708, 10); // ---- HUD part 3: control hints ---- fill("#7f8aa3"); textSize(9); textAlign(LEFT, CENTER); text("drag sliders | Run/Pause animates the drive | Reset", 300, 501); // ---- live status: which of the 3 failure modes is active ---- textAlign(RIGHT, CENTER); textSize(10); let flag = "in range", col = "#7fe08a"; if (peak > Vsat) { flag = "CLIPPING (range)"; col = "#ff6b6b"; } else if (f > fc) { flag = "LAG (bandwidth)"; col = "#ffb347"; } else if (sig > 0 && peak < 3 * sig) { flag = "BURIED (noise)"; col = "#c08bff"; } fill(col); text(flag, 708, 501); // ---- HUD part 4: live equation footer (above the control band) ---- const dr = (sig > 0) ? (20 * log(Vsat / sig) / log(10)) : Infinity; const drStr = (sig > 0) ? (nf(dr, 0, 1) + " dB") : "inf"; noStroke(); fill("#0b0f18"); rect(0, FOOTY, width, 28); fill("#aab6d6"); textSize(11); textAlign(LEFT, CENTER); text("V = clamp(S*A*G*sin(2pi f t + phi), +/-Vsat) + noise", 10, FOOTY + 14); textAlign(RIGHT, CENTER); fill("#cfe0ff"); text("G=" + nf(G, 0, 2) + " phi=" + nf(degrees(phi), 0, 0) + " deg DR=" + drStr, 712, FOOTY + 14); } // ===================================================================== // controls // ===================================================================== function toggleRun() { running = !running; btnRun.html(running ? "Pause" : "Run"); if (running) loop(); else { noLoop(); redraw(); } } function resetAll() { sldS.value(DEF.S); sldA.value(DEF.A); sldF.value(DEF.f); sldFc.value(DEF.fc); sldVsat.value(DEF.Vsat); sldSig.value(DEF.sig); tsec = 0; running = false; btnRun.html("Run"); noLoop(); redraw(); } ``` <!-- REAL-GENERATIVE-MEDIA:START --> ## The model this MicroSim animates However different two transducers look, they share the same input-output description. Drive an input **measurand** `x(t)` and the transducer returns an electrical output `V(t)`. Four characteristics - the same four used to *rate* real transducers - decide how faithfully it does so. This sketch makes each one a control you can move. **1. Sensitivity / the transfer characteristic.** The output is a function of the input, `V = f(x)`. Near an operating point the curve is locally a straight line whose slope is the **sensitivity** `S = dV/dx` (output per unit input - e.g. mV per unit, mV/V for a load cell, uV/K for a thermocouple). The left panel draws this **transfer characteristic**: a line of slope `S`. **2. Range / saturation.** No real characteristic is a line forever; beyond the full-scale output it **saturates**, flattening into plateaus at `+/-Vsat`. Drive the input past the point where `|S * x| > Vsat` and the output **clips** - the peaks of the waveform are shorn flat. **3. Bandwidth / dynamic response.** A transducer cannot follow an input instantly. Modelled as a first-order [[System|system]] with a `-3 dB` cutoff `fc`, its sinusoidal **gain** rolls off and its output **lags** the input: ``` G(f) = 1 / sqrt(1 + (f/fc)^2) (amplitude gain, <= 1) phi(f) = -atan(f/fc) (phase lag, radians) ``` Below `fc` the output rides faithfully on the characteristic line; as `f` approaches and passes `fc` the amplitude shrinks and the operating point opens from a line into a lagging **ellipse** (a Lissajous loop) on the transfer plot - the visual signature of finite bandwidth. **4. Noise floor / dynamic range.** Every transducer adds random **noise** to its output (in electrical transducers, the thermal motion of charge). Noise of RMS value `sigma` corrupts *small* signals far more than large ones. The ratio of the largest faithfully translated signal to the smallest sets the **dynamic range**: ``` DR = 20 * log10(Vsat / sigma) dB ``` Putting it together, the output the sketch plots is the steady-state sinusoidal response ``` V(t) = clamp( S * A * G(f) * sin(2*pi*f*t + phi(f)), -Vsat, +Vsat ) + noise(sigma) x(t) = A * sin(2*pi*f*t) ``` The "aha" is that **one input can fail to convert in three different ways**: it can be *clipped* (too big for the range), *attenuated and delayed* (too fast for the bandwidth), or *buried* (too small for the noise floor) - and the transfer characteristic shows you which is happening. ## Links (Wikipedia order) <!-- injected from _registry/childlinks/Transducer.json (2026-07-30T02:09:12Z) --> `Accelerometer` · `Actuator` · [[Alternating_current]] · `Amplifier` · `Amplitude` · `Antenna_(radio)` · `Audio_signal` · `Automation` · `Backlash_(engineering)` · [[Communications_system]] · [[Control_system]] · [[Cybernetics]] · `Disk_read-and-write_head` · [[Dynamic_range]] · `Electrical_conductor` · `Electro-galvanic_oxygen_sensor` · `Electroactive_polymer` · `Electrometer` · [[Electronics]] · [[Energy_transformation]] · `Finite-state_transducer` · `Fluorescent_lamp` · `Galvanometer` · `Gear_train` · `Geophone` · `Hall_effect_sensor` · `Human` · `Hydrophone` · `Hysteresis` · `Laser_diode` · `Light-emitting_diode` · `Linear_motor` · `Linear_variable_differential_transformer` · `List_of_sensors` · `Load_cell` · [[Loudspeaker]] · `Magnetic_cartridge` · `Magnetic_field` · `Microphone` · `Motion` · `Noise_(signal_processing)` · `Photodetector` · `Photodiode` · `Photomultiplier` · `Photoresistor` · `Pickup_(music_technology)` · `Piezoelectric_sensor` · `Potentiometer` · `Radio_receiver` · `Radio_wave` · [[Repeatability]] · `Robot` · `Rotary_variable_differential_transformer` · [[Sensor]] · [[Signal]] · `Software` · `Sound` · `Strain_gauge` · `Tactile_sensor` · `Tape_head` · `Thermistor` · `Thermocouple` · `Thermophone` · `Transceiver` · `Transmitter` · `Ultrasound` · `Vibrating_structure_gyroscope` · `Voice_coil` · [[Voltage]] · `Wireless` ## From the Real GENERATIVE library ![Transducer](https://upload.wikimedia.org/wikipedia/commons/thumb/7/7d/Mechanical_transducer._-_DPLA_-_cfb11a91bbe9ab7384f897fb55faf74c_%28page_4%29.jpg/220px-Mechanical_transducer._-_DPLA_-_cfb11a91bbe9ab7384f897fb55faf74c_%28page_4%29.jpg) *Transducer — placed from the Real G.E.N.E.R.A.T.I.V.E. course library (Energy room). Source: Wikimedia Commons (via Wikipedia article media). [Details & license](https://commons.wikimedia.org/wiki/File:Mechanical_transducer._-_DPLA_-_cfb11a91bbe9ab7384f897fb55faf74c_%28page_4%29.jpg).* > A transducer is a device that converts energy from one form to another. Usually a transducer converts a signal in one form of energy to a signal in another.[1] Transducers are often employed at the boundaries of automation, measurement, and control systems, where electrical signals are converted to and from other physical quantities (energy, force, torque, l ([Wikipedia](https://en.wikipedia.org/wiki/Transducer)) <!-- REAL-GENERATIVE-MEDIA:END --> ## Overview A **transducer** is a device that usefully converts [[Energy|energy]] from one form to another - most often a **[[Signal|signal]]** carried in one form of energy into a signal carried in another. The conversion itself is called **transduction**. Transducers live at the boundaries of measurement, automation, and control systems, where physical quantities ([[Force|force]], pressure, temperature, light, position, sound, magnetic field) are turned into electrical signals and back again. Transducers are classified by the direction [[Information|information]] flows through them: - A **sensor** is an *input* transducer: it responds to a stimulus from the physical world and produces a signal that represents it (a thermocouple turning a temperature difference into a small [[Voltage|voltage]]; an LVDT turning displacement into an AC signal; a load cell turning force into mV/V). - An **actuator** is an *output* transducer: it takes a signal from a [[Control_system|control system]] and converts a source of energy into motion, sound, light, or heat (a [[Loudspeaker|loudspeaker]], a motor, an LED). - A **bidirectional** transducer works both ways. An antenna converts radio waves to a current and a current to radio waves; a voice coil is a loudspeaker run forwards and a dynamic microphone run backwards. This **reciprocity** is a defining feature of the family. A second axis is the power source: **passive** transducers need an external **excitation** signal that they modulate (a thermistor only reveals its resistance when a current is passed through it), while **active** (self-generating) transducers produce their own output directly from the stimulus (a photodiode, a thermocouple, a piezoelectric crystal). ## Parameter table (each control -> real symbol + range) | Control | Symbol | Physical meaning | Range | Default | |---|---|---|---|---| | Sensitivity | `S` | transfer ratio = slope of the characteristic, output per unit input | 5 - 60 mV/unit | 20 mV/unit | | Input amplitude | `A` | half-span of the driven measurand `x(t)` | 0 - 10 units | 7 units | | Drive frequency | `f` | frequency of the input measurand | 0.2 - 20 Hz | 2 Hz | | Bandwidth | `fc` | -3 dB cutoff of the first-order dynamic response | 0.5 - 20 Hz | 6 Hz | | Range (saturation) | `Vsat` | full-scale output limit (+/-) where the curve flattens | 50 - 400 mV | 200 mV | | Noise floor | `sigma` | RMS additive output noise | 0 - 20 mV | 0 mV | Derived and shown live in the HUD: gain `G = 1/sqrt(1+(f/fc)^2)`, phase lag `phi = -atan(f/fc)` (degrees), and dynamic range `DR = 20 log10(Vsat/sigma)` dB. Controls: six sliders, plus **Run/Pause** (animate the drive) and **Reset** (restore every value, phase, and the paused state). ## Learning objective Explain how a transducer's **sensitivity, range, bandwidth, and noise floor** together determine which inputs it can faithfully convert - and predict, by reading the transfer characteristic and the input/output traces, **when the output will clip, when it will lag and shrink, and when it will vanish into noise**. ## A-V pattern A composition: a **G** system block-diagram strip (measurand -> transducer -> output) over a quantitative **transfer-characteristic chart** (output vs input, left) and an **H** signals-over-time pair of traces (input and output waveforms, right). The dynamic operating point traces a Lissajous loop on the chart to expose bandwidth lag. ## Sources - Transducer - Wikipedia: https://en.wikipedia.org/wiki/Transducer <!-- CRAFT-LINK:START g12 --> *Built to the [[WT!P5_js_Microsim_Master_Class|p5.js Master Class]].* <!-- CRAFT-LINK:END --> ## Wikipedia : Wikitube **Strict pair:** [Wikipedia](https://en.wikipedia.org/wiki/Transducer) : [Wikitube](https://en.wikitube.io/wiki/Transducer) ## Previous hub tags Tree parent: [[Hydrogen]]. Legacy hubs: none. --- *Sources: 1 legacy note. Minted wave 1, 2026-07-30 (v1.6 order).*