<!--date=20250219 -->


<h1>Signal Generators</h1>
<p>A signal generator produces a controlled electrical signal — sine, square, triangle, or arbitrary waveform — at a specified frequency and amplitude. They're essential for electronics testing and development: you need a known, clean signal to characterise a filter, test an amplifier's frequency response, verify ADC sampling, or inject a tone into an audio circuit. Understanding what's available (from the humble 555 to a modern DDS bench instrument) lets you pick the right tool for the job.</p>

<h2>Types of Signal Generators</h2>

<table>
  <thead><tr><th>Type</th><th>Frequency range</th><th>Output waveforms</th><th>Accuracy</th><th>Cost range</th></tr></thead>
  <tbody>
    <tr><td>555 timer (astable)</td><td>1 Hz – ~500 kHz</td><td>Square (approximate)</td><td>Poor (±10–20%)</td><td>Cents</td></tr>
    <tr><td>MCU PWM</td><td>DC – ~1 MHz</td><td>Square (+ filtered sine)</td><td>Moderate (crystal-limited)</td><td>Already have one</td></tr>
    <tr><td>AD9833 DDS module</td><td>0 – 12.5 MHz</td><td>Sine, triangle, square</td><td>Good (±0.1 Hz)</td><td>$2–5</td></tr>
    <tr><td>Si5351 clock gen</td><td>8 kHz – 160 MHz</td><td>Square (3 independent outputs)</td><td>Good</td><td>$5–10</td></tr>
    <tr><td>Analog bench function gen</td><td>0.1 Hz – 20 MHz</td><td>Sine, square, triangle, ramp</td><td>Good (DDS-based internally)</td><td>$50–500</td></tr>
    <tr><td>AWG (arbitrary waveform gen)</td><td>DC – GHz range</td><td>Any user-defined waveform</td><td>Very good</td><td>$200 – $50,000+</td></tr>
    <tr><td>RF signal generator</td><td>100 kHz – 40 GHz</td><td>Modulated RF carrier</td><td>Excellent (synthesised)</td><td>$500 – $100,000+</td></tr>
  </tbody>
</table>

<h2>Function Generators</h2>
<p>The classic bench instrument for audio and RF development. Modern function generators are DDS-based internally — a DAC clocked at high speed reads a waveform lookup table, producing the output frequency and shape. Key specs to look for:</p>

<table>
  <thead><tr><th>Spec</th><th>What to look for</th><th>Why it matters</th></tr></thead>
  <tbody>
    <tr><td>Max frequency</td><td>At least 10× your highest frequency of interest</td><td>Square wave edges contain harmonics well above fundamental</td></tr>
    <tr><td>Frequency resolution</td><td>µHz to mHz resolution in DDS instruments</td><td>Fine-tune beat frequencies, PLL testing</td></tr>
    <tr><td>Amplitude range</td><td>1mVpp to 10–20Vpp</td><td>Injecting signals into sensitive circuits needs small amplitudes</td></tr>
    <tr><td>DC offset</td><td>Adjustable ± supply range</td><td>Biasing signals to ADC input range, testing with DC component</td></tr>
    <tr><td>Output impedance</td><td>50Ω (standard)</td><td>Matches coaxial cable and RF equipment; affects amplitude at load</td></tr>
    <tr><td>Modulation</td><td>AM, FM, PM, sweep</td><td>Testing receiver sensitivity, PLL lock range, filter characterisation</td></tr>
  </tbody>
</table>

<h2>AD9833 — Cheap DDS Module</h2>
<pre>
The AD9833 is an SPI-controlled DDS IC producing sine, triangle, or square waves
from DC to 12.5 MHz with 28-bit frequency resolution.

Frequency register = f_desired × 2^28 / f_MCLK

Example (f_MCLK = 25MHz):
  1 kHz:  FREQ_REG = 1000 × 268435456 / 25000000 = 10,737
  10 kHz: FREQ_REG = 10000 × 268435456 / 25000000 = 107,374
  1 MHz:  FREQ_REG = 1000000 × 268435456 / 25000000 = 10,737,418

SPI write sequence (16-bit frames):
  1. Write control register (reset, waveform type)
  2. Write lower 14 bits of frequency word
  3. Write upper 14 bits
  4. Release reset — output begins
</pre>

<h2>Si5351 Clock Generator</h2>
<pre>
Three independent clock outputs, each 8kHz – 160MHz.
Commonly used as a variable frequency oscillator (VFO) for radio.

Control via I2C:
  PLL A and B: each multiplied from crystal reference (25 or 27MHz)
  Each output: divided down from PLL

Output frequency = (f_xtal × a + b/c) / d
  where a, b, c, d are programmed dividers

Libraries (Si5351Arduino by NT7S) handle all the register math:
  si5351.set_freq(1000000ULL * 100, SI5351_CLK0);  // 100 MHz on CLK0
</pre>

<h2>555 Timer as Signal Generator</h2>
<pre>
Astable (free-running oscillator):

        VCC
         │
        [RA]
         │
         ●── PIN 7 (discharge)
        [RB]
         │
         ●── PIN 2, 6 (threshold/trigger)
        [C]
         │
        GND

f = 1.44 / ((RA + 2×RB) × C)
Duty cycle = (RA + RB) / (RA + 2×RB)

Note: standard 555 cannot achieve exactly 50% duty cycle in astable mode.
Use TLC555 or LMC555 (CMOS) with equal R and steering diodes for 50%:

         D1      D2
VCC ─[RA]──►├──┬──┤◄──[RB]─ PIN7
                │
               [C]
                │
               GND

Charge: through RA, D1 (bypasses RB)
Discharge: through RB, D2 (bypasses RA)
With RA=RB: duty ≈ 50%
</pre>

<h2>Microcontroller as Signal Generator</h2>

<h3>PWM Square Wave</h3>
<pre>
Any MCU with a timer peripheral can generate square waves:

Arduino (hardware PWM, pin 9):
  TCCR1B = (TCCR1B &amp; 0xF8) | 0x01;  // no prescaler, ~31kHz base
  analogWrite(9, 127);               // ~50% duty, ~31kHz

Or: direct tone():
  tone(9, 1000);   // 1kHz square wave on pin 9, blocking

For precise frequency: use ICR1 mode (16-bit timer):
  ICR1 = F_CPU / (prescaler × frequency) - 1
</pre>

<h3>Sine Wave via DAC + Low-Pass Filter</h3>
<pre>
Generate sine wave from lookup table via DAC:
  1. Create table of N samples per cycle: sine_table[N]
  2. Output each sample via DAC at rate f_sample
  3. Sine output frequency = f_sample / N
  4. Low-pass filter after DAC removes step artifacts

Arduino Uno with R-2R DAC (8-bit, 8 pins):
  f_sample ≈ 40kHz (limited by loop speed + DAC settling)
  For 1kHz sine: N = 40 samples per cycle

Raspberry Pi Pico with 12-bit DAC (MCP4725):
  f_sample up to ~100kHz via DMA
  For 1kHz: 100 samples per cycle, very clean output
</pre>

<h2>Scope Usage with Signal Generator</h2>

<table>
  <thead><tr><th>Measurement</th><th>Signal generator setting</th><th>Scope setup</th></tr></thead>
  <tbody>
    <tr><td>Filter frequency response</td><td>Sweep frequency, constant amplitude</td><td>Measure output amplitude at each frequency; plot</td></tr>
    <tr><td>Amplifier gain</td><td>Known amplitude at target frequency</td><td>Compare output to input — gain = Vout/Vin</td></tr>
    <tr><td>Amplifier distortion</td><td>Sine at rated frequency and amplitude</td><td>FFT mode on scope — harmonics show distortion</td></tr>
    <tr><td>ADC sampling test</td><td>Sine at known frequency below Nyquist</td><td>Sample and reconstruct — check for aliasing</td></tr>
    <tr><td>RC time constant</td><td>Low-frequency square wave (period >> 5τ)</td><td>Watch exponential charging on scope</td></tr>
  </tbody>
</table>

<h2>References</h2>
<ul>
  <li>Horowitz &amp; Hill — <em>The Art of Electronics</em>, 3rd ed. Chapter 7</li>
  <li><a href="https://www.analog.com/en/products/ad9833.html" target="_blank" rel="noopener">AD9833 datasheet — Analog Devices ↗</a></li>
  <li><a href="https://github.com/etherkit/Si5351Arduino" target="_blank" rel="noopener">Si5351 Arduino Library (NT7S) ↗</a></li>
  <li><a href="https://www.rigolna.com/products/waveform-generators/" target="_blank" rel="noopener">Rigol DG Series — affordable bench function generators ↗</a></li>
</ul>
