พิมพ์คำที่ต้องการค้นหา ทั้งภาษาไทยและอังกฤษ

  1. หน้าแรก
  2. คลังความรู้
  3. แล็บ FG + สโคป
  4. สร้างเครื่องเอง

// บทที่ 12.8 · แล็บ FG + สโคป · Build Your Own

สร้างเครื่องกำเนิดสัญญาณเอง: 555 ออสซิลเลเตอร์ Wien และ DDS AD9833

เข้าใจเครื่องมือดีที่สุดคือสร้างมันเอง หน้านี้ไล่จากวงจรที่ใช้ชิ้นส่วนไม่กี่ตัว ไปจนถึงเครื่องกำเนิดสัญญาณแบบดิจิทัลที่หลักการเหมือนเครื่องในห้องแล็บ พร้อมโค้ด Arduino และ ESP32 และปิดท้ายด้วยวงจรขาเข้าของสโคปทำเอง ทุกวงจรใช้ความรู้จากหน้าก่อน ๆ: RC τ, ออปแอมป์ ชมิตต์ทริกเกอร์ และ DDS สูตรใช้รหัส K

เขียนโดย อาจารย์มดอัปเดต
สรุปใน 30 วินาที
  • สี่เหลี่ยมง่ายสุด: 555 f=1.44/((RA+2RB)C)f = 1.44/((R_A + 2R_B)C) หรือออปแอมป์ผ่อนคลาย T=2RCln⁡3T = 2RC\ln 3 (R1=R2R_1 = R_2)
  • ไซน์แอนะล็อก: Wien bridge f0=1/(2πRC)f_0 = 1/(2\pi RC) เกนต้องเท่ากับ 3 พอดีและต้องมีวงจรคุมแอมพลิจูด
  • ดิจิทัล: ตารางค่าไซน์ + DAC หรือ DDS: fout=Mfclk/2Nf_{out} = M f_{clk}/2^N · AD9833: M=f⋅228/25 MHzM = f\cdot 2^{28}/25\ \text{MHz}
  • ภาคขาออก: ออปแอมป์ที่สลูว์เรตพอ + 50 Ω อนุกรม เหมือนเครื่องจริง
ระดับพื้นฐาน ม.ปลาย · ปวส. · ปี 1กลาง ป.ตรี วิศวกรรมขั้นสูง ป.โท · งานวิจัย

เลือกแบบไหนดี พื้นฐาน

แบบรูปคลื่นช่วงความถี่โดยประมาณความยากเหมาะกับ
ออปแอมป์ผ่อนคลายสี่เหลี่ยม (+ เอกซ์โพเนนเชียลบน C)Hz – หลายสิบ kHzง่ายเรียนป้อนกลับบวก ชมิตต์ RC
ชมิตต์ + อินทิเกรเตอร์สี่เหลี่ยม + สามเหลี่ยมHz – หลายสิบ kHzง่าย–กลาง“ฟังก์ชันเจเนอเรเตอร์” แบบแอนะล็อกแท้
ไอซี 555สี่เหลี่ยม< 1 Hz – ราว 100 kHzง่ายมากไฟกะพริบ เสียง สัญญาณนาฬิกา
Wien bridgeไซน์เพี้ยนต่ำ10 Hz – 100 kHzกลางไซน์เสียงคุณภาพดี เรียน Barkhausen
XR2206ไซน์ สามเหลี่ยม สี่เหลี่ยมHz – ราว 1 MHzง่าย (มีชุดคิท)เครื่องตั้งโต๊ะราคาประหยัด
MCU + DAC/R-2Rอะไรก็ได้ (ตาราง)ถึงราว 10–50 kHzกลางรูปคลื่นพิเศษ เรียนการสุ่มและ DAC
DDS AD9833ไซน์ สามเหลี่ยม สี่เหลี่ยม0.1 Hz – ราว 10 MHzกลางเครื่องกำเนิดสัญญาณใช้งานจริง ตั้งค่าแม่น

ออสซิลเลเตอร์ผ่อนคลายด้วยออปแอมป์ พื้นฐาน กลาง

วงจรนี้คือ ชมิตต์ทริกเกอร์ ที่เอาขาออกของตัวเองมาชาร์จตัวเก็บประจุผ่าน R เมื่อแรงดันบน C ขึ้นถึง +βVsat+\beta V_{sat} ขาออกพลิกเป็นลบ C เริ่มคายลงจนถึง −βVsat-\beta V_{sat} แล้วพลิกกลับ วนไปเรื่อย ๆ เป็นการประยุกต์ ผลตอบสนองอันดับหนึ่ง R2 โดยตรง

+−CRR₁R₂v_Cv_oβ = R₂/(R₁+R₂)+βV_sat−βV_satเหลือง v_C (เอกซ์โพเนนเชียล) · ฟ้า v_o (สี่เหลี่ยม)
ออสซิลเลเตอร์ผ่อนคลาย: ขาออกเป็นสี่เหลี่ยม แรงดันบน C เป็นเส้นโค้งเอกซ์โพเนนเชียลระหว่างสองระดับของชมิตต์ทริกเกอร์

K1 Feedback fraction อัตราส่วนป้อนกลับบวก

β=R2R1+R2,VTH,TL=±βVsat\beta = \frac{R_2}{R_1 + R_2},\qquad V_{TH,TL} = \pm\beta V_{sat}

K2 Relaxation-oscillator period คาบของออสซิลเลเตอร์ผ่อนคลาย

T=2RCln⁡1+β1−β,R1=R2: T=2RCln⁡3=2.197 RCT = 2RC\ln\frac{1 + \beta}{1 - \beta},\qquad R_1 = R_2:\ T = 2RC\ln 3 = 2.197\,RC

มาจากเวลาที่ C ชาร์จจาก −βVsat-\beta V_{sat} เข้าหา +Vsat+V_{sat} จนถึง +βVsat+\beta V_{sat} ใช้ R3

ตัวอย่าง K-1 · ออสซิลเลเตอร์ราว 1 kHz

R = 10 kΩ, C = 47 nF, R1=R2R_1 = R_2 = 10 kΩ ได้ความถี่เท่าไร

  1. β=0.5\beta = 0.5 K1 แล้วใช้ K2

    T=2(104)(47×10−9)ln⁡3=1.033 msT = 2(10^4)(47\times10^{-9})\ln 3 = 1.033\ \text{ms}
  2. ความถี่

    f=11.033 ms=968 Hzf = \frac{1}{1.033\ \text{ms}} = 968\ \text{Hz}

ราว 968 Hz สมมาตร 50 % อยากปรับความถี่ให้ใช้โพเทนชิออมิเตอร์แทน R อยากได้ดิวตี้ไม่เท่ากันให้ใช้ไดโอดสองตัวแยกทางชาร์จกับทางคาย ผ่าน R คนละค่า

เครื่องกำเนิดสี่เหลี่ยม-สามเหลี่ยม: ชมิตต์ + อินทิเกรเตอร์ กลาง

แทน RC ด้วย อินทิเกรเตอร์ ประจุจะเพิ่มด้วยกระแสคงที่ Vsat/RV_{sat}/R แรงดันจึงเป็นเส้นตรง ได้สามเหลี่ยมแท้ ต่อขาออกอินทิเกรเตอร์เข้า ชมิตต์แบบไม่กลับเฟส และขาออกชมิตต์ (สี่เหลี่ยม) เข้าอินทิเกรเตอร์ วนเป็นวง นี่คือแกนของเครื่องกำเนิดสัญญาณแอนะล็อกรุ่นเก่าและไอซีอย่าง XR2206 ถ้าต้องการไซน์ ให้ป้อนสามเหลี่ยมเข้าวงจรปั้นรูป (diode shaper) ที่ตัดยอดให้โค้ง

K3 Square–triangle generator เครื่องกำเนิดสี่เหลี่ยม-สามเหลี่ยม

f=R24R1RC,V△,peak=±R1R2Vsatf = \frac{R_2}{4R_1RC},\qquad V_{\triangle,peak} = \pm\frac{R_1}{R_2}V_{sat}

R1R_1 ขาเข้าชมิตต์ R2R_2 ป้อนกลับชมิตต์ · R, C ของอินทิเกรเตอร์ · ปรับความถี่ด้วย R โดยแอมพลิจูดสามเหลี่ยมไม่เปลี่ยน

ตัวอย่าง K-2 · ออกแบบ 5 kHz

R1R_1 = 10 kΩ, R2R_2 = 20 kΩ, R = 10 kΩ, C = 10 nF ไฟ ±15 V (VsatV_{sat} ≈ 13.5 V) หาความถี่และแอมพลิจูดสามเหลี่ยม

  1. ความถี่ K3

    f=20 0004(10 000)(10 000)(10×10−9)=24×10−4=5 kHzf = \frac{20\,000}{4(10\,000)(10\,000)(10\times10^{-9})} = \frac{2}{4\times10^{-4}} = 5\ \text{kHz}
  2. แอมพลิจูด

    ±1020(13.5)=±6.75 V (13.5 Vpp)\pm\frac{10}{20}(13.5) = \pm 6.75\ \text{V}\ (13.5\ \text{Vpp})

สามเหลี่ยม 13.5 Vpp ที่ 5 kHz และสี่เหลี่ยม ±13.5 V ต้องตรวจสลูว์เรตด้วย ขอบสี่เหลี่ยม 27 V ด้วย LM741 ใช้เวลาราว 54 µs เทียบกับคาบ 200 µs ขอบจะเอียงชัดเจน ใช้ TL081 หรือคอมพาเรเตอร์ LM393 แทน

ไอซี 555 แบบ astable พื้นฐาน

555 มีคอมพาเรเตอร์สองตัวเทียบแรงดันบน C กับ ⅓ และ ⅔ ของไฟเลี้ยง ฟลิปฟล็อปภายในสั่งทรานซิสเตอร์ขา 7 ให้คายประจุ C ชาร์จผ่าน RA+RBR_A + R_B และคายผ่าน RBR_B จึงได้สี่เหลี่ยมที่ช่วงสูงยาวกว่าช่วงต่ำเสมอ ใช้ไฟ 4.5–15 V (NE555) หรือ 2–15 V (รุ่น CMOS เช่น 7555 กินกระแสน้อยกว่าและขอบสะอาดกว่า)

+V_CCR_AR_BCNE5557 DIS6 THR2 TRG3 OUT8415v_COUT⅔V_CC⅓V_CCบน v_C · ล่าง ขาออกขา 8 และ 4 ต่อ +V_CC · ขา 5 ต่อ 10 nF ลงกราวด์
555 แบบ astable: ช่วง tHt_H C ชาร์จจาก ⅓ ถึง ⅔ VCCV_{CC} ผ่าน RA+RBR_A + R_B ช่วง tLt_L คายจาก ⅔ ถึง ⅓ ผ่าน RBR_B

K4 555 high and low times เวลาสูงและต่ำของ 555

tH=ln⁡2 (RA+RB)C,tL=ln⁡2 RBCt_H = \ln 2\,(R_A + R_B)C,\qquad t_L = \ln 2\,R_B C

ln⁡2=0.693\ln 2 = 0.693 มาจากการชาร์จจาก ⅓ ถึง ⅔ ซึ่งคือครึ่งหนึ่งของระยะที่เหลือถึง VCCV_{CC}

K5 555 frequency and duty cycle ความถี่และดิวตี้ของ 555

f=1.44(RA+2RB)C,D=RA+RBRA+2RBf = \frac{1.44}{(R_A + 2R_B)C},\qquad D = \frac{R_A + R_B}{R_A + 2R_B}

D>50 %D > 50\ \% เสมอ ถ้าต้องการต่ำกว่า 50 % ต่อไดโอดขนาน RBR_B ให้กระแสชาร์จข้าม RBR_B แล้ว tH≈0.693RACt_H \approx 0.693R_AC

ตัวอย่าง K-3 · 555 ราว 7 kHz

RAR_A = 1 kΩ, RBR_B = 10 kΩ, C = 10 nF หาเวลาสูง เวลาต่ำ ความถี่ และดิวตี้

  1. เวลา K4

    tH=0.693(11 k)(10 n)=76.2 μs,tL=0.693(10 k)(10 n)=69.3 μst_H = 0.693(11\ \text{k})(10\ \text{n}) = 76.2\ \mu\text{s},\quad t_L = 0.693(10\ \text{k})(10\ \text{n}) = 69.3\ \mu\text{s}
  2. ความถี่และดิวตี้ K5

    f=1.44(21 k)(10 n)=6.86 kHz,D=1121=52.4 %f = \frac{1.44}{(21\ \text{k})(10\ \text{n})} = 6.86\ \text{kHz},\quad D = \frac{11}{21} = 52.4\ \%

6.86 kHz ดิวตี้ 52.4 % วัดด้วยสโคป: CH1 ที่ขา 6 (เห็นเลื่อยระหว่าง ⅓ ถึง ⅔ VCCV_{CC}) CH2 ที่ขา 3 ใช้การวัดอัตโนมัติ Freq และ Duty เทียบ ค่าจริงมักต่างได้ราว 5–10 % ตามค่าคลาดเคลื่อนของ C

ไซน์แอนะล็อก: Wien bridge และ RC phase-shift กลาง ขั้นสูง

ออสซิลเลเตอร์ไซน์คือวงจรขยายที่ป้อนกลับตัวเองผ่านตัวกรองที่ให้เฟสพอดีเพียงความถี่เดียว เครือข่าย Wien (RC อนุกรมต่อกับ RC ขนาน) ให้เฟส 0° และอัตราส่วน 1/3 ที่ f0f_0 เครื่องขยายไม่กลับเฟสเกน 3 จึงทำให้เกนวงรอบเท่ากับ 1 พอดี ตามเงื่อนไขของ Barkhausen นี่คือวงจรที่ Hewlett-Packard ใช้ในเครื่องกำเนิดสัญญาณเครื่องแรก (HP200A ปี 1939) ซึ่งใช้หลอดไฟเป็นตัวคุมแอมพลิจูด

+−CRRCR_f = 2R_gR_gCH1CH2f₀ = 1/(2πRC)ที่ f₀: β = 1/3, เฟส 0°ต้องการเกน A = 3+ คุมแอมพลิจูด:ไดโอดคู่ขนาน R_f บางส่วนหรือหลอดไฟ / JFET / NTC
Wien bridge: ป้อนกลับบวกผ่าน RC (ขวาบนและซ้ายล่าง) กำหนดความถี่ ป้อนกลับลบผ่าน RfR_f, RgR_g กำหนดเกน 3

K6 Wien-bridge frequency ความถี่ของ Wien bridge

f0=12πRC,β(f0)=V+Vo=13f_0 = \frac{1}{2\pi RC},\qquad \beta(f_0) = \frac{V_+}{V_o} = \frac13

กรณี R และ C สองชุดไม่เท่ากัน: f0=1/(2πR1R2C1C2)f_0 = 1/(2\pi\sqrt{R_1R_2C_1C_2})

K7 Required gain เกนที่ต้องการ

A=1+RfRg=3⇒Rf=2RgA = 1 + \frac{R_f}{R_g} = 3\quad\Rightarrow\quad R_f = 2R_g

เริ่มต้นตั้งเกนสูงกว่า 3 เล็กน้อยให้แกว่งได้เอง แล้วให้ไดโอด หลอดไฟ หรือ JFET ลดเกนลงเมื่อแอมพลิจูดโต

K8 Barkhausen criterion เงื่อนไขการแกว่งของ Barkhausen

A β(jω0)=1∠0∘A\,\beta(j\omega_0) = 1\angle 0^\circ

เป็นเงื่อนไขจำเป็นสำหรับการแกว่งต่อเนื่อง ขนาดเกนวงรอบ = 1 และเฟสรอบวง = 0° (หรือ 360°)

K9 RC phase-shift oscillator ออสซิลเลเตอร์เลื่อนเฟส RC

f0=12πRC6,∣A∣≥29f_0 = \frac{1}{2\pi RC\sqrt6},\qquad |A| \ge 29

RC สูงผ่านสามภาคเลื่อนเฟสรวม 180° ต่อกับวงจรขยายกลับเฟส (อีก 180°) ที่เกนอย่างน้อย 29

ตัวอย่าง K-4 · ไซน์ 1 kHz สองแบบ

(ก) Wien bridge R = 10 kΩ, C = 16 nF (ข) phase-shift R = 10 kΩ, C = 10 nF ได้ความถี่เท่าไร

  1. (ก) K6

    f0=12π(104)(16×10−9)=995 Hzf_0 = \frac{1}{2\pi(10^4)(16\times10^{-9})} = 995\ \text{Hz}
  2. (ข) K9

    f0=12π(104)(10−8)6=650 Hzf_0 = \frac{1}{2\pi(10^4)(10^{-8})\sqrt6} = 650\ \text{Hz}

Wien ได้ราว 1 kHz และปรับความถี่ง่ายด้วยโพเทนชิออมิเตอร์คู่ (สเตอริโอ) แทน R ทั้งสองตัว ส่วน phase-shift ต้องปรับ R สามตัวพร้อมกัน จึงนิยมใช้แบบความถี่คงที่ ตรวจความเพี้ยนของไซน์ด้วย FFT บนสโคป X10

ไอซีฟังก์ชันเจเนอเรเตอร์ XR2206 พื้นฐาน

XR2206 รวมออสซิลเลเตอร์ควบคุมด้วยแรงดัน วงจรปั้นไซน์ และภาคขาออกไว้ในชิปเดียว ชุดคิทราคาประหยัดให้ไซน์ สามเหลี่ยม และสี่เหลี่ยม ตั้งย่านความถี่ด้วยสวิตช์เลือกตัวเก็บประจุและปรับละเอียดด้วยโพเทนชิออมิเตอร์ เป็นเครื่องแรกที่ดีสำหรับโต๊ะทำงานที่บ้าน แต่ความถี่ลอยตามอุณหภูมิและไซน์เพี้ยนราว 0.5–2 % มากกว่า DDS

K10 XR2206 frequency ความถี่ของ XR2206

f0=1RCf_0 = \frac{1}{RC}

R คือตัวต้านทานตั้งเวลา (เอกสารข้อมูลแนะนำราว 4 kΩ–200 kΩ เพื่อความเสถียร) C คือตัวเก็บประจุตั้งเวลา เช่น R = 10 kΩ, C = 100 nF ได้ 1 kHz

ไมโครคอนโทรลเลอร์ + DAC: ตารางค่าไซน์ กลาง

เก็บค่าไซน์หนึ่งคาบไว้ในตาราง (look-up table) แล้วส่งออก DAC ทีละค่าด้วยอัตราคงที่ ความถี่ขาออกเท่ากับอัตราส่งหารด้วยจำนวนจุดในตาราง DAC ที่ทำเองง่ายที่สุดคือบันไดตัวต้านทาน R-2R ต่อกับขาดิจิทัลหลายขา ใช้ตัวต้านทานแค่สองค่า

D0 (LSB)2RD12RD22RD3 (MSB)2RRRR2R+−V_outV_out = V_ref·(8D₃ + 4D₂ + 2D₁ + D₀)/16 · R = 10 kΩ, 2R = 20 kΩ (1 % หรือดีกว่า)
DAC แบบ R-2R สี่บิต: แต่ละบิตมีน้ำหนักเป็นครึ่งหนึ่งของบิตถัดไป ขยายเป็น 8 บิตได้โดยเพิ่มขั้นบันได ต่อบัฟเฟอร์ออปแอมป์เพื่อไม่ให้โหลดดึงแรงดัน

K11 DAC output and LUT frequency แรงดัน DAC และความถี่จากตาราง

Vout=VrefD2n,ΔV=Vref2n,fout=fupdateNLUTV_{out} = V_{ref}\frac{D}{2^n},\qquad \Delta V = \frac{V_{ref}}{2^n},\qquad f_{out} = \frac{f_{update}}{N_{LUT}}

8 บิต 5 V: ขั้นละ 19.5 mV · ตาราง 64 จุดที่ 100 kSa/s ได้ 1.56 kHz · ต้องมีตัวกรองต่ำผ่านลบขั้นบันได (ภาพสะท้อนที่ fupdate±foutf_{update} \pm f_{out})

โค้ด Arduino Uno: R-2R 8 บิตบนพอร์ต D (D0–D7) ส่งไซน์ 64 จุดต่อคาบ ค่า 0–255 ได้แรงดัน 0–5 V

// Arduino Uno: 8-bit R-2R DAC on PORTD (D0–D7), 64-point sine table
// Disconnect D0/D1 (USB serial) from the ladder while uploading.
const uint8_t N = 64;
uint8_t lut[N];

void setup() {
  DDRD = 0xFF;                                   // D0–D7 as outputs
  for (uint8_t i = 0; i < N; i++)
    lut[i] = 128 + 127 * sin(2 * PI * i / N);    // 1 … 255
}

void loop() {
  for (uint8_t i = 0; i < N; i++) {
    PORTD = lut[i];                              // write all 8 bits at once
    delayMicroseconds(10);                       // ≈ 11 µs per point → ≈ 1.4 kHz
  }
}

ความถี่จริงขึ้นกับเวลาของลูป ให้วัดด้วยสโคป ถ้าต้องการความถี่แม่นให้ใช้ timer interrupt ส่งค่าทุก ๆ ช่วงเวลาคงที่

ESP32 รุ่นดั้งเดิม (ESP32-WROOM/WROVER) มี DAC 8 บิตในตัวสองช่องที่ GPIO25 และ GPIO26 ไม่ต้องต่อ R-2R ส่วน ESP32-S2 มี DAC ที่ GPIO17/18 แต่ ESP32-S3 และ ESP32-C3 ไม่มี DAC ต้องใช้ PWM + ตัวกรอง (ดู PWM กับแรงดันเฉลี่ย) หรือ DAC ภายนอก

// ESP32 (classic): built-in 8-bit DAC on GPIO25, 64-point sine
const int N = 64;
uint8_t lut[N];
void setup() {
  for (int i = 0; i < N; i++) lut[i] = 128 + 127 * sin(2 * PI * i / N);
}
void loop() {
  for (int i = 0; i < N; i++) {
    dacWrite(25, lut[i]);                        // 0 … 255 → about 0 … 3.3 V
    delayMicroseconds(20);
  }
}

DDS ด้วย AD9833: เครื่องกำเนิดสัญญาณที่ใช้งานได้จริง กลาง ขั้นสูง

DDS คือการทำตารางค่าไซน์ให้ความถี่ละเอียดมาก แทนที่จะเดินทีละจุดในตาราง ตัวสะสมเฟส NN บิตจะบวกเลข MM ทุกสัญญาณนาฬิกา แล้วใช้บิตบน ๆ ของเฟสเปิดตาราง ความถี่ขาออกจึงปรับได้ทีละ fclk/2Nf_{clk}/2^N หลักการอยู่ที่ หน้าเครื่องกำเนิดสัญญาณ (V15–V18) ลองเล่นตัวสะสมเฟสด้านล่าง: เพิ่ม M แล้ววงล้อหมุนเร็วขึ้น จุดต่อคาบน้อยลง ขั้นบันไดหยาบขึ้น และเมื่อ M เกินครึ่งวง ความถี่ที่เห็นจะกลับลดลง (อเลียส)

AD9833 เป็น DDS ขนาดเล็กราคาประหยัด ตัวสะสมเฟส 28 บิต DAC 10 บิต โมดูลทั่วไปมีคริสตัล 25 MHz ให้ไซน์และสามเหลี่ยมราว 0.6 Vpp (มีระดับ DC ราว 0.3 V) และสี่เหลี่ยมระดับลอจิก ความละเอียดความถี่ 25 MHz/228=0.09325\ \text{MHz}/2^{28} = 0.093 Hz คุมด้วย SPI สามสาย

Arduino / ESP32ปุ่ม จอ เอนโค้ดเดอร์AD9833DDS 25 MHzกรอง + Cตัด DCออปแอมป์เกน + ออฟเซตSPI0.6 Vpp50 ΩBNCปุ่ม Amplitude, OffsetSPI 3 สาย: SCLK, SDATA, FSYNC · AD9833 ใช้ไฟ 2.3–5.5 V กราวด์ร่วมกับบอร์ดArduino Uno: D13 → SCLK, D11 → SDATA, D10 → FSYNCESP32: GPIO18 → SCLK, GPIO23 → SDATA, GPIO5 → FSYNC
เครื่องกำเนิดสัญญาณ DDS ทำเอง: โครงสร้างเดียวกับเครื่องในห้องแล็บ (ดู บล็อกไดอะแกรมเครื่องจริง)

K12 AD9833 frequency register ค่าที่เขียนลงรีจิสเตอร์ AD9833

M=round ⁣(fout 228fMCLK),LSB=0x4000 ∣ (M & 0x3FFF),MSB=0x4000 ∣ (M≫14)M = \text{round}\!\left(\frac{f_{out}\,2^{28}}{f_{MCLK}}\right),\quad \text{LSB} = \texttt{0x4000}\,|\,(M \,\&\, \texttt{0x3FFF}),\quad \text{MSB} = \texttt{0x4000}\,|\,(M \gg 14)

ลำดับ: 0x2100 (B28 = 1, RESET) → LSB → MSB → 0xC000 (PHASE0 = 0) → 0x2000 ไซน์ / 0x2002 สามเหลี่ยม / 0x2028 สี่เหลี่ยม

ตัวอย่าง K-5 · ตั้ง AD9833 ที่ 12,345.6 Hz

นาฬิกา 25 MHz หาเลข M คำที่ต้องเขียนลง FREQ0 และความถี่ที่ได้จริง

  1. เลขปรับความถี่ K12

    M=round ⁣(12 345.6×268 435 45625 000 000)=132 560M = \text{round}\!\left(\frac{12\,345.6 \times 268\,435\,456}{25\,000\,000}\right) = 132\,560
  2. แยกเป็นสองคำ 14 บิต

    132 560=8×16 384+1488⇒LSB=0x45D0, MSB=0x4008132\,560 = 8\times16\,384 + 1488 \Rightarrow \text{LSB} = \texttt{0x45D0},\ \text{MSB} = \texttt{0x4008}
  3. ความถี่จริง V15

    f=132 560×25×106228=12 345.61 Hzf = \frac{132\,560 \times 25\times10^6}{2^{28}} = 12\,345.61\ \text{Hz}

เขียน 0x2100, 0x45D0, 0x4008, 0xC000, 0x2000 ได้ 12,345.61 Hz คลาดเคลื่อน 0.01 Hz ความแม่นยำจริงขึ้นกับคริสตัล (ราว ±50 ppm หรือ ±0.6 Hz ที่ความถี่นี้)

// AD9833 DDS with Arduino Uno (SCLK D13, SDATA D11, FSYNC D10) or ESP32 (18, 23, 5)
#include <SPI.h>
const int   FSYNC = 10;          // ESP32: 5
const float MCLK  = 25e6;        // crystal on the module

void ad9833Write(uint16_t w) {
  SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE2));
  digitalWrite(FSYNC, LOW);
  SPI.transfer16(w);
  digitalWrite(FSYNC, HIGH);
  SPI.endTransaction();
}

// mode: 0x2000 sine, 0x2002 triangle, 0x2028 square
void ad9833Set(float f, uint16_t mode) {
  uint32_t M = (uint32_t)(f * 268435456.0 / MCLK + 0.5);   // K12
  ad9833Write(0x2100);                      // B28 = 1, reset
  ad9833Write(0x4000 | (M & 0x3FFF));       // FREQ0 LSB
  ad9833Write(0x4000 | ((M >> 14) & 0x3FFF)); // FREQ0 MSB
  ad9833Write(0xC000);                      // PHASE0 = 0
  ad9833Write(mode);                        // leave reset, choose waveform
}

void setup() {
  pinMode(FSYNC, OUTPUT);
  digitalWrite(FSYNC, HIGH);
  SPI.begin();
  ad9833Set(1000.0, 0x2000);                // 1 kHz sine
}

void loop() {}

ขยายต่อ: อ่านเอนโค้ดเดอร์แบบหมุนเพื่อปรับความถี่ แสดงผลบนจอ OLED หรือรับคำสั่งความถี่ทาง Serial ก็ได้ สำหรับการกวาดความถี่ ให้เรียก ad9833Set() ในลูปด้วยความถี่ที่เพิ่มทีละขั้น (เขียนเฉพาะ LSB/MSB ก็พอ ไม่ต้องรีเซ็ตทุกครั้งเพื่อให้เฟสต่อเนื่อง)

ภาคขาออก: แอมพลิจูด ออฟเซต และ 50 Ω กลาง

ขาออก DDS เล็กและมี DC ปนอยู่ ต้องตัด DC ด้วยตัวเก็บประจุ ปรับขนาดด้วยโพเทนชิออมิเตอร์ แล้วใช้ วงจรรวมสัญญาณ บวกออฟเซต DC ที่ปรับได้ ก่อนออกขั้วผ่านตัวต้านทาน 50 Ω เหมือนเครื่องจริง V1 ข้อที่มักลืมคือสลูว์เรตของออปแอมป์ภาคนี้ต้องพอสำหรับความถี่และแอมพลิจูดสูงสุดที่ต้องการ

K13 Output stage ภาคขาออก

vout=G (vdds−vˉdds)+Voff,SR≥2πfmaxVp,maxv_{out} = G\,(v_{dds} - \bar v_{dds}) + V_{off},\qquad SR \ge 2\pi f_{max}V_{p,max}

GG จากโพเทนชิออมิเตอร์และเกนออปแอมป์ · VoffV_{off} จากโพเทนชิออมิเตอร์ต่อ ±V ผ่านวงจรรวม · ตรวจขีดจำกัด ∣Voff∣+Vp≤Vsat|V_{off}| + V_p \le V_{sat}

ตัวอย่าง K-6 · เลือกออปแอมป์ภาคขาออก

ต้องการ 10 Vpp (High-Z) ถึง 1 MHz ออปแอมป์ต้องมีสลูว์เรตเท่าไร TL081 ใช้ได้ไหม

  1. Vp=5V_p = 5 V K13 U6

    SR≥2π(106)(5)=31.4 V/μsSR \ge 2\pi(10^6)(5) = 31.4\ \text{V/}\mu\text{s}
  2. TL081 มี 13 V/µs ได้แค่

    fFPBW=13×1062π×5=414 kHzf_{FPBW} = \frac{13\times10^6}{2\pi\times5} = 414\ \text{kHz}

TL081 ไม่พอ ต้องใช้ออปแอมป์ความเร็วสูงที่มี SR หลักร้อย V/µs และ GBW หลายสิบ MHz ขึ้นไป เช่น LM7171 หรือออปแอมป์แบบป้อนกลับกระแส (current-feedback) และต้องวางลายวงจรสั้น มีกราวด์เพลน ถ้าใช้แค่ย่านเสียง (≤ 20 kHz) TL072 เหลือเฟือ

ออสซิลโลสโคปทำเอง: ขาเข้า การสุ่ม และขีดจำกัด กลาง

หลักการสโคปดิจิทัลคือ ภาคขาเข้า (ลดทอน ยกระดับ ป้องกัน) → ADC → หน่วยความจำ → ทริกเกอร์ → วาดจอ ทำเองด้วยไมโครคอนโทรลเลอร์ได้ แต่ต้องเข้าใจขีดจำกัดของ ADC และต้องแปลงสัญญาณ ±V ให้อยู่ในช่วงที่ ADC รับได้ (0–3.3 V หรือ 0–5 V) ก่อนเสมอ ไม่เช่นนั้นขา ADC เสีย

V_in ±10 VR₁ = 100 kΩR₂ = 47 kΩR₃ = 33 kΩ+3.3 V+3.3 VADCV_adc = k·V_in + V_biask = R_b/(R₁ + R_b) ≈ 0.162R_b = R₂ ∥ R₃V_bias ≈ 1.62 V±10 V → 0.00 … 3.25 V
ภาคขาเข้า: ตัวแบ่งแรงดันสามตัวลดทอนและยกระดับในคราวเดียว ไดโอดหนีบไว้กันแรงดันเกิน (ใช้ไดโอด Schottky)

K14 ADC front-end (divider + bias) วงจรแบ่งแรงดันและยกระดับ

Vadc=k Vin+Vth(1−k),k=RbR1+Rb,Rb=R2∥R3,Vth=VrefR2R2+R3V_{adc} = k\,V_{in} + V_{th}(1 - k),\quad k = \frac{R_b}{R_1 + R_b},\quad R_b = R_2\parallel R_3,\quad V_{th} = V_{ref}\frac{R_2}{R_2 + R_3}

ออกแบบ: เลือก k=(Vref/2)/Vin,maxk = (V_{ref}/2)/V_{in,max} และให้ Vadc=Vref/2V_{adc} = V_{ref}/2 เมื่อ Vin=0V_{in} = 0

K15 ADC sample rate อัตราสุ่มของ ADC

fs=fADC13,fmax<fs2  (ใช้จริง≈fs/5 ถึง fs/10)f_s = \frac{f_{ADC}}{13},\qquad f_{max} < \frac{f_s}{2}\ \ \text{(ใช้จริง} \approx f_s/5 \text{ ถึง } f_s/10)

Arduino Uno: fADC=16 MHz/128=125f_{ADC} = 16\ \text{MHz}/128 = 125 kHz → 9.6 kSa/s · การ์ดเสียง 48–192 kSa/s แต่คัปปลิง AC ที่ขาเข้า · ESP32 เร็วกว่าแต่ ADC ไม่เป็นเชิงเส้นช่วงปลาย ต้องสอบเทียบ

ตัวอย่าง K-7 · ±10 V เข้า ADC 3.3 V

ใช้ R1R_1 = 100 kΩ ออกแบบ R2R_2, R3R_3 ให้ ±10 V เป็น 0–3.3 V

  1. อัตราส่วนที่ต้องการ K14

    k=1.6510=0.165 ⇒ Rb=kR11−k=19.8 kΩk = \frac{1.65}{10} = 0.165\ \Rightarrow\ R_b = \frac{k R_1}{1 - k} = 19.8\ \text{k}\Omega
  2. Vadc(0)=1.65V_{adc}(0) = 1.65 V

    Vth=1.651−k=1.98 V⇒R2R2+R3=0.599V_{th} = \frac{1.65}{1 - k} = 1.98\ \text{V} \Rightarrow \frac{R_2}{R_2 + R_3} = 0.599
  3. แก้สองสมการ

    R3=Rb0.599=33.0 kΩ,R2=Rb1−0.599=49.3 kΩR_3 = \frac{R_b}{0.599} = 33.0\ \text{k}\Omega,\quad R_2 = \frac{R_b}{1 - 0.599} = 49.3\ \text{k}\Omega
  4. ใช้ค่ามาตรฐาน R2R_2 = 47 kΩ, R3R_3 = 33 kΩ ตรวจ

    Rb=19.4 kΩ, k=0.162, Vth=1.94 V⇒Vadc=1.62±1.62 VR_b = 19.4\ \text{k}\Omega,\ k = 0.162,\ V_{th} = 1.94\ \text{V} \Rightarrow V_{adc} = 1.62 \pm 1.62\ \text{V}

±10 V กลายเป็น 0.00–3.25 V อยู่ในช่วง ADC ในโปรแกรมแปลงกลับด้วย Vin=(Vadc−1.62)/0.162V_{in} = (V_{adc} - 1.62)/0.162 แล้วสอบเทียบกับแหล่งจ่าย DC ที่รู้ค่าอีกครั้ง

// Arduino Uno: minimal "scope" — 400 samples as fast as analogRead allows, then send to Serial Plotter
const int NS = 400;
int buf[NS];
void setup() { Serial.begin(115200); }
void loop() {
  unsigned long t0 = micros();
  for (int i = 0; i < NS; i++) buf[i] = analogRead(A0);      // ≈ 104 µs each
  float dt = (micros() - t0) / (float)NS;                      // µs per sample
  for (int i = 0; i < NS; i++) {
    float vadc = buf[i] * 5.0 / 1023.0;
    Serial.println(vadc);                                      // convert with K14 for a divider
  }
  delay(200);
}

เพิ่มทริกเกอร์ได้โดยวนอ่านจนค่าข้ามระดับที่กำหนดขาขึ้นก่อนเริ่มเก็บ 400 จุด เป็นหลักการเดียวกับทริกเกอร์ของสโคปจริง ทริกเกอร์

เช็กลิสต์ก่อนเปิดไฟและวิธีทดสอบเครื่องที่สร้างเอง พื้นฐาน

  1. ตรวจขั้วไฟเลี้ยงและกราวด์ร่วมของทุกบอร์ดก่อนเสียบ ใส่ 100 nF คร่อมไฟเลี้ยงทุกไอซี

  2. เปิดไฟผ่านแหล่งจ่ายที่จำกัดกระแส (เริ่ม 50–100 mA) ดูว่ากินกระแสผิดปกติหรือไม่

  3. วัดความถี่ด้วยสโคปจริงหรือฟังก์ชัน counter เทียบกับสูตร ความต่างเกิน 10 % ให้ตรวจค่าชิ้นส่วน

  4. ดูรูปคลื่นที่ขาออกเมื่อเปิดวงจร (High-Z) และเมื่อต่อโหลด 50 Ω ควรลดลงครึ่งหนึ่งพอดี V3

  5. ดู FFT ของไซน์: ฮาร์มอนิกที่สองและสามควรต่ำกว่าพื้นฐานอย่างน้อย 40 dB สำหรับงานเสียง X10

  6. กวาดความถี่ทั้งย่าน ตรวจว่าแอมพลิจูดไม่ตก (สลูว์เรต แบนด์วิดท์) และไม่มีการแกว่งแปลกปลอม

ถ้ายังไม่มีชิ้นส่วน ลองทุกการวัดบน แล็บจำลอง ก่อน แล้วไปดู งานประยุกต์ ที่ใช้เครื่องเหล่านี้

คำถามที่พบบ่อย

สร้างเครื่องกำเนิดสัญญาณเองแบบไหนง่ายและคุ้มที่สุด?

ถ้าต้องการแค่คลื่นสี่เหลี่ยม ใช้ไอซี 555 หรือขา PWM ของไมโครคอนโทรลเลอร์ ถ้าต้องการไซน์ สามเหลี่ยม และสี่เหลี่ยมที่ตั้งความถี่ได้แม่นจาก 0.1 Hz ถึงหลาย MHz ใช้โมดูล DDS AD9833 คุมด้วย Arduino หรือ ESP32 ผ่าน SPI สามสาย แล้วเพิ่มภาคขยายด้วยออปแอมป์สำหรับปรับแอมพลิจูดและออฟเซต

AD9833 ตั้งค่าความถี่อย่างไร?

คำนวณเลข 28 บิต M = round(f_out × 2²⁸ / f_MCLK) เช่น 1 kHz กับนาฬิกา 25 MHz ได้ M = 10737 แล้วเขียนเป็นสองคำ 14 บิตลงรีจิสเตอร์ FREQ0 โดยตั้งบิตบนเป็น 01 (0x4000 | ค่า) ลำดับคือ 0x2100 (รีเซ็ต) คำล่าง คำบน 0xC000 (เฟส) แล้ว 0x2000 สำหรับไซน์ 0x2002 สามเหลี่ยม หรือ 0x2028 สี่เหลี่ยม

Arduino ใช้เป็นออสซิลโลสโคปได้ไหม?

ได้สำหรับสัญญาณช้า Arduino Uno อ่าน ADC ได้ราว 9.6 kSa/s ด้วย analogRead จึงดูได้แค่ไม่กี่ร้อย Hz ถึงราว 1 kHz และรับได้เฉพาะ 0–5 V ต้องมีวงจรแบ่งแรงดันและยกระดับก่อนวัดสัญญาณที่มีค่าลบ ESP32 และการ์ดเสียงคอมพิวเตอร์เร็วกว่า แต่ยังห่างจากสโคปจริงมาก เหมาะกับการเรียนรู้หลักการสุ่มสัญญาณ

ทำไมออสซิลเลเตอร์ Wien bridge ต้องมีวงจรคุมแอมพลิจูด?

เงื่อนไข Barkhausen ต้องการเกนวงรอบเท่ากับ 1 พอดี ถ้าเกนน้อยกว่า 3 นิดเดียวการแกว่งจะหยุด ถ้ามากกว่านิดเดียวแอมพลิจูดจะโตจนออปแอมป์อิ่มตัวและไซน์ถูกตัดยอด จึงต้องมีชิ้นส่วนที่ลดเกนเมื่อแอมพลิจูดสูง เช่น ไดโอดคู่ขนานกับตัวต้านทานป้อนกลับบางส่วน หลอดไฟ หรือ JFET

อาจารย์มด · ธีรวุฒิ แสวงบุญ
อาจารย์สาขาวิชาวิศวกรรมไฟฟ้า มหาวิทยาลัยราชภัฏธนบุรี สมุทรปราการ · ดูโปรไฟล์