บทที่ 3 · สัญญาณดิจิทัล ADC และ Interface
บทที่ 3 · Digital Signals, ADC & Sensor Interfaces

สัญญาณดิจิทัล ADC และ Interface

บทที่แล้วจบที่แรงดันที่พร้อมวัดแต่ยังเป็นอนาล็อก บทนี้ตอบว่าแรงดันกลายเป็นตัวเลขได้อย่างไร และตัวเลขถูกส่งระหว่างอุปกรณ์อย่างไร

เรียบเรียงจาก [1] INS03_Digital_Signals_v9

เมื่อจบบทนี้ ผู้เรียนควรสามารถ

  • แปลงเลขฐานสอง ฐานสิบหก และฐานสิบ และอ่านค่าจากข้อมูลดิบของเซนเซอร์
  • คำนวณความละเอียดของ ADC และแยก “ความละเอียด” ออกจาก “ความแม่นยำ”
  • อธิบายการทำงานของ DAC และ SAR ADC และเปรียบเทียบ ADC ตระกูลต่าง ๆ
  • ตั้งค่า ADC ของ ESP32 (ช่อง, attenuation) ได้อย่างถูกต้อง
  • เปรียบเทียบ UART, RS-232, RS-485/Modbus, I²C, SPI, 1-Wire และ CAN แล้วเลือกใช้ให้เหมาะกับงาน

3.1บิต ไบต์ และเลขฐานสิบหก

หน่วยขนาดจำนวนค่าความหมาย / ตัวอย่าง
Bit1 บิต2 (0/1)LOW/HIGH หรือ 0 V / 3.3 V
Byte8 บิต256 (0–255)หน่วยที่ UART, I²C, SPI ส่ง
Word16 บิต65,536ค่าใน Modbus, ค่าจาก ADC 12 บิต

เลขฐานสิบหก 1 หลักแทน 4 บิตพอดี ดังนั้น 1 ไบต์ = 2 หลัก hex เขียนในโค้ดเป็น 0x57 (บางเอกสารเขียน 57h) แปลงทีละ 4 บิต แทนการหารยาว

HexBinaryคำนวณDecimalที่มา
0x570101 01115×16 + 787I²C address ของ ultrasonic
0x3C0011 11003×16 + 1260I²C address ของ OLED
0x010A—1×256 + 0×16 + 10266อุณหภูมิจาก XY-MD02 → ÷10 = 26.6 °C
0x0F0000 11111515

3.2Quantization และความละเอียด

ADC ขนาด n บิตแบ่งช่วงแรงดันอินพุตออกเป็น 2n ระดับ แต่ละระดับกว้าง 1 LSB ค่าที่อยู่ระหว่างระดับจะถูกปัดลง ความกว้างของหนึ่งระดับคือความละเอียด (resolution)

1 LSB = Vref2n  ;  V = code2n × Vref
บิตจำนวนระดับพบใน
8256DAC ของ ESP32, เซนเซอร์ราคาถูก
101,024Arduino UNO, ESP8266
124,096ESP32, Raspberry Pi Pico
1665,536ADS1115
2416.7 ล้านHX711 (load cell), MAX31865
Quantization 3 บิต: สัญญาณอนาล็อก (เส้นแดง) ถูกแทนด้วยค่าเพียง 8 ระดับ (000–111) ที่จุดสุ่มแต่ละจุด (เส้นน้ำเงิน) — ความต่างระหว่างสองเส้นคือ quantization error
รูปที่ 3.1 Quantization 3 บิต: สัญญาณอนาล็อก (เส้นแดง) ถูกแทนด้วยค่าเพียง 8 ระดับ (000–111) ที่จุดสุ่มแต่ละจุด (เส้นน้ำเงิน) — ความต่างระหว่างสองเส้นคือ quantization error ภาพ: Hyacinth / Wikimedia Commons, CC BY-SA 3.0

ตัวอย่าง: ADC 12 บิต, Vref = 3.3 V → 1 LSB = 3.3/4096 ≈ 0.8 mV

ความละเอียด ≠ ความแม่นยำ ความละเอียดบอกเพียงว่า ADC แยกความต่าง 0.8 mV ได้ แต่ ESP32 ที่ยังไม่สอบเทียบอาจอ่านคลาดเคลื่อนได้ 100–200 mV ในโครงงาน error 100 mV ของเซนเซอร์ความชื้นดินแบบ capacitive ทำให้ความชื้นผิดไปหลายเปอร์เซ็นต์ — จึงต้องสอบเทียบ 6 จุดใน Activity 4.1

3.3DAC: จากบิตเป็นแรงดัน

เรียน DAC ก่อนเพราะ SAR ADC มี DAC อยู่ภายใน (ESP32 เองก็มี DAC 8 บิต 2 ช่องที่ GPIO25 และ GPIO26)

Binary-weighted DAC

ข้อจำกัด: DAC 16 บิตต้องใช้ตัวต้านทานที่ค่ามากสุดและน้อยสุดต่างกัน 215 = 32,768 เท่า และทุกตัวต้องแม่นยำ ซึ่งผลิตจริงไม่ได้

ทางออกคือ R-2R ladder ที่ใช้ตัวต้านทานเพียงสองค่า (R และ 2R) ไม่ว่าจะกี่บิต

3.4ADC พื้นฐานและ SAR

ADC แบบป้อนกลับทุกชนิดมีโครงสร้างเดียวกัน[6]:

แผนภาพบล็อกของ SAR ADC: วงจร sample-and-hold (S/H), comparator, DAC และ SAR register ที่ส่งบิต DN−1…D0 ออกมา
รูปที่ 3.2 แผนภาพบล็อกของ SAR ADC: วงจร sample-and-hold (S/H), comparator, DAC และ SAR register ที่ส่งบิต DN−1…D0 ออกมา ภาพ: White Flye / Wikimedia Commons, CC BY-SA 2.5

Digital-ramp ADC นับขึ้นทีละ 1 จากศูนย์จนกว่า VDAC จะตามทัน Vin — ช้า (สูงสุด 2N ครั้ง) และเวลาแปลงขึ้นกับอินพุต

SAR (Successive Approximation Register) ทำงานแบบ binary search: เริ่มจากบิต MSB ค่าทดลองแรก 100… = Vref/2 ถ้า VDAC ไม่เกิน Vin ให้คงบิตไว้ (1) ถ้าเกินให้ล้างบิต (0) แล้วทำบิตถัดไป — ใช้ n ขั้นเสมอ

ตัวอย่าง: SAR 4 บิต, Vref = 15 V, Vin = 10.1 V

0 5 10 15 V Vin = 10.1 V 7.50 11.25 9.375 10.31 1000 1100 1010 1011 คง b3 ล้าง b2 คง b1 ล้าง b0
รูปที่ 3.3 VDAC ของรหัสทดลองแต่ละขั้น (เขียว = ไม่เกิน Vin คงบิต, แดง = เกิน ล้างบิต)
ขั้นรหัสทดลองVDACเทียบผล
i = 310008/16 × 15 = 7.50 V7.50 < 10.1คง b3 = 1
i = 2110012/16 × 15 = 11.25 V11.25 > 10.1ล้าง b2 = 0
i = 1101010/16 × 15 = 9.375 V9.375 < 10.1คง b1 = 1
i = 0101111/16 × 15 = 10.31 V10.31 > 10.1ล้าง b0 = 0

ผลลัพธ์ 10102 = 10 → V = 10/16 × 15 = 9.375 V คลาดจริงไม่เกิน 1 LSB (0.94 V)

SAR ต้องมีวงจร sample-and-hold — ถ้า Vin เปลี่ยนระหว่างการแปลง ผลจะผิดโดยไม่มีสัญญาณเตือน ESP32 มี SAR ADC 12 บิต 2 ชุด (ADC1, ADC2) ที่มี Vref ภายในประมาณ 1.1 V จึงต้องใช้ attenuation (หัวข้อ 3.6)

3.5ตระกูล ADC และการสุ่มตัวอย่าง

ชนิดหลักการความละเอียด / ความเร็วพบใน
SARBinary search, n clock ต่อ n บิต ต้องมี sample-and-hold8–16 บิต, kHz–MHz · สมดุลที่สุดสำหรับ MCUESP32, Arduino, Pi Pico
FlashComparator 2n − 1 ตัวเทียบพร้อมกันใน 1 cycle6–8 บิต, ระดับ GHz · แพงและกินไฟOscilloscope, วิดีโอ
Pipelineหลายขั้นต่อกัน แต่ละขั้นแก้ไม่กี่บิตแล้วส่งส่วนที่เหลือต่อ10–16 บิต, MHz · มี latency หลาย clockการสื่อสาร, กล้อง
Delta-Sigma (ΔΣ)สุ่มเร็วมากด้วย comparator 1 บิต แล้ว digital filter เฉลี่ย16–24 บิต, Hz–kHz · ทนสัญญาณรบกวนดีมากHX711, ADS1115, MAX31865
Dual-slopeIntegrator ชาร์จด้วย Vin เวลา T1 แล้วคายด้วย −Vref จนเป็นศูนย์ที่เวลา T2ช้ามากแต่แม่นยำ · T2 ∝ Vin ไม่ขึ้นกับ R, Cมัลติมิเตอร์, ตาชั่ง
Flash ADC 2 บิต: comparator 3 ตัว (2n − 1) เทียบ VIN กับแรงดันจากโซ่ตัวต้านทานพร้อมกัน แล้ววงจรตรรกะเข้ารหัสเป็นบิต
รูปที่ 3.4 Flash ADC 2 บิต: comparator 3 ตัว (2n − 1) เทียบ VIN กับแรงดันจากโซ่ตัวต้านทานพร้อมกัน แล้ววงจรตรรกะเข้ารหัสเป็นบิต ภาพ: Jon Guerber / Wikimedia Commons, CC BY 3.0
ΔΣ ADC อันดับหนึ่ง: modulator (integrator + comparator 1 บิต + DAC 1 บิตป้อนกลับ) ตามด้วย digital filter และ decimator
รูปที่ 3.5 ΔΣ ADC อันดับหนึ่ง: modulator (integrator + comparator 1 บิต + DAC 1 บิตป้อนกลับ) ตามด้วย digital filter และ decimator ภาพ: Lambtron / Wikimedia Commons, CC BY-SA 4.0
สัญญาณเกษตรส่วนใหญ่เปลี่ยนช้า แต่ต้องการความละเอียดสูงและทนสัญญาณรบกวน สำหรับสัญญาณระดับ mV เช่น load cell หรือ thermocouple ชิป ΔΣ ภายนอก (HX711, ADS1115) มักดีกว่า SAR ในตัว MCU · Dual-slope ที่เลือก T1 = 20 ms จะเฉลี่ยสัญญาณรบกวน 50 Hz ทิ้งได้หมดพอดี

การสุ่มตัวอย่าง (Sampling)

fs > 2fmax ทฤษฎีบท Nyquist

ถ้าสุ่มช้ากว่านี้จะเกิด aliasing ซึ่งกรองออกภายหลังไม่ได้ เซนเซอร์เกษตรส่วนใหญ่ เช่น อุณหภูมิหรือความชื้นดิน เปลี่ยนช้ามาก สุ่มทุก 1–10 นาทีก็พอ แต่ต้องระวังพัลส์จาก flow meter และสัญญาณรบกวน 50 Hz — ใช้ low-pass filter (บทที่ 2) ก่อนสุ่ม

Aliasing: คลื่นไซน์ความถี่สูง (แดง) ถูกสุ่มช้าเกินไป จุดที่ได้ (สีดำ) จึงดูเหมือนคลื่นความถี่ต่ำ (น้ำเงิน) ที่ไม่มีอยู่จริง
รูปที่ 3.6 Aliasing: คลื่นไซน์ความถี่สูง (แดง) ถูกสุ่มช้าเกินไป จุดที่ได้ (สีดำ) จึงดูเหมือนคลื่นความถี่ต่ำ (น้ำเงิน) ที่ไม่มีอยู่จริง ภาพ: Moxfyre / Wikimedia Commons, CC BY-SA 3.0

3.6ADC ของ ESP32 และ Attenuation

บอร์ดพัฒนา ESP32 DevKit ที่ใช้โมดูล ESP-WROOM-32
รูปที่ 3.7 บอร์ดพัฒนา ESP32 DevKit ที่ใช้โมดูล ESP-WROOM-32 ภาพ: Ubahnverleih / Wikimedia Commons, CC0

ข้อมูลในหัวข้อนี้สรุปจากเอกสารของ Espressif[2][3] และผลการวัดของ Llamas[4] และ Monk[5] ตามที่อ้างใน INS03

หัวข้อรายละเอียด
ความละเอียดSAR 12 บิต (0–4095) ปรับได้ 9–12 บิตด้วย analogReadResolution()
ช่อง18 ช่อง · ADC1: GPIO32–39 · ADC2: GPIO0, 2, 4, 12–15, 25–27
ADC2 กับ WiFiADC2 ใช้วงจรร่วมกับ WiFi อ่านไม่ได้ขณะเปิด WiFi — โครงงานใช้ ADC1 เท่านั้น (Activity 4.1 ใช้ GPIO34)
Vref≈ 1.1 V สร้างในชิป แต่ต่างกันในแต่ละชิป (1.0–1.2 V) ถ้าไม่สอบเทียบคลาดได้ ±10%
ช่วงอินพุตแกน ADC วัดได้ 0 ถึง Vref ขยายช่วงด้วย attenuation 0 / 2.5 / 6 / 11 dB (analogSetAttenuation())
ความเป็นเชิงเส้นดีช่วงกลาง ต่ำกว่า ≈ 0.1 V อ่านได้ศูนย์ และที่ 11 dB โค้งงอเหนือ ≈ 2.45 V
ความเร็วสูงสุด ≈ 100 kS/s ต่อช่องด้วย ESP-IDF — analogRead() ช้ากว่ามากแต่เหลือเฟือ ใช้เวลาว่างอ่านหลายครั้งแล้วเฉลี่ย

Attenuation คือวงจรแบ่งแรงดันในชิป

แกน ADC วัดได้เพียง 0–1.1 V เสมอ สิ่งที่เราเลือกคือวงจรแบ่งแรงดันด้านหน้า (แบบเดียวกับที่ต่อใน Lab 1) อัตราส่วนแรงดันจาก dB คือ k = 10dB/20 และช่วงเต็มสเกล = 1.1 V × k

ค่าใน ArduinodBk1.1 V × kช่วงเชิงเส้น
ADC_0db01.01.1 V100–950 mV
ADC_2_5db2.51.331.5 V100–1250 mV
ADC_6db62.02.2 V150–1750 mV
ADC_11db (DB_12)11 (≈12)3.6 (≈4)3.9 V*150–2450 mV

* ขาของ ESP32 รับได้ไม่เกิน 3.3 V · ค่าจริงของ 11 dB ใกล้ 12 dB (≈ 4 เท่า) Espressif จึงเปลี่ยนชื่อเป็น DB_12 ใน ESP-IDF 5

กับดักที่พบบ่อย
  • 11 dB ไม่ได้แปลว่า “ช่วง 3.3 V” แต่แปลว่าหาร 3.6 และเป็นเชิงเส้นถึงประมาณ 2.45 V เท่านั้น
  • ค่า raw 3723 และ 2097 อาจเป็นแรงดันเดียวกันที่ attenuation ต่างกัน — บันทึก raw count คู่กับ attenuation และ Vref ของชิปนั้นเสมอ
  • เกินช่วงแล้วอิ่มตัวเงียบ ๆ: ค่าค้างที่ 4095 แปลงกลับได้เพียง ≈ 1.8–2.2 V แทนค่าจริง 3.15 V (มัลติมิเตอร์จะแสดง “OL” แต่ ADC ไม่เตือน)

การเลือกช่วง: ให้ค่าสูงสุดของเซนเซอร์อยู่ที่ 60–90% ของช่วงเชิงเส้น สำหรับเซนเซอร์ 0–3.3 V มีสองทางเลือก (1) ใช้ 11 dB แล้วสอบเทียบ 6 จุด (Activity 4.1) หรือ (2) ต่อวงจรแบ่งแรงดันภายนอกลดเหลือ 0–2.2 V แล้วใช้ 6 dB ฟังก์ชัน analogReadMilliVolts() ใช้ค่าสอบเทียบจากโรงงานใน eFuse ดีกว่า analogRead() แต่ยังควรตรวจกับมัลติมิเตอร์อย่างน้อย 2 จุด

กฎของรายวิชา: วัดก่อนคำนวณ — raw count จะเป็นแรงดันได้ก็ต่อเมื่อคำนึงถึง Vref, attenuation และการสอบเทียบของบอร์ดนั้น

3.7ทำไมเซนเซอร์จึงเป็นดิจิทัล

  1. MCU ไม่ว่าง: การจับเวลาพัลส์ (HC-SR04, 1-Wire) ต้องการ MCU ว่างระดับ µs แต่ WiFi/LoRa ขัดจังหวะตลอด ค่าจึงกระโดดเป็นครั้งคราว
  2. สัญญาณรบกวน: สายอนาล็อกยาวรับ 50 Hz และสัญญาณรบกวนจากมอเตอร์ เฟรมดิจิทัลมี checksum/CRC จึงตรวจพบความผิดพลาดแทนที่ค่าจะเพี้ยนเงียบ ๆ
  3. ระยะทาง: ADC ต้องการสายสั้น ขณะที่ RS-485 ไปได้ 1,200 m และ 1-Wire หลายสิบเมตร
  4. เซนเซอร์รายงานสถานะได้: ตาชั่งส่ง ST/US (นิ่ง/ไม่นิ่ง), GPS ส่งคุณภาพ fix, Modbus ส่ง error code

ข้อแลกเปลี่ยนคือต้องเรียนรู้ “ภาษา” ของแต่ละ interface ซึ่งมีสองชั้น:

ชั้นกายภาพ (Physical layer)ชั้นโปรโตคอล (Protocol layer)
แรงดันใดแทน 0 และ 1 (3.3 V, ±12 V, differential)รูปแบบเฟรม: เริ่ม-จบตรงไหน กี่บิต
ใช้สายกี่เส้น เส้นใดใช้ร่วมกันมี address หรือไม่ ใครกำหนด
ระยะทางและความทนสัญญาณรบกวนใครให้ clock: สาย clock แยก หรือตกลงความเร็วล่วงหน้า
ต้องมี pull-up หรือ terminator หรือไม่ตรวจความผิดพลาดอย่างไร: parity, checksum, CRC, ACK
สองหลักการที่ใช้ตลอดบท ① ระยะทางเป็นเรื่องของชั้นกายภาพ — เฟรม UART เดียวกันไปได้ ~1 m บน TTL แต่ 1,200 m บน RS-485
② Address คือสิ่งที่แยก bus ออกจาก point-to-point — มี address จึงต่อหลายอุปกรณ์บนสายชุดเดียวได้

3.8UART, RS-232 และ RS-485

UART: เฟรมแบบ asynchronous

แผนภาพเวลาของหนึ่งเฟรม UART: start bit ตามด้วย data bit 0–7 (ส่งบิตต่ำสุดก่อน) และ stop bit
รูปที่ 3.8 แผนภาพเวลาของหนึ่งเฟรม UART: start bit ตามด้วย data bit 0–7 (ส่งบิตต่ำสุดก่อน) และ stop bit ภาพ: IngenieroLoco / Wikimedia Commons, CC BY-SA 4.0

ASCII หรือ Binary

ASCIIBinary
การอ่านอ่านได้ทันทีใน Serial Monitor แทบไม่ต้องใช้ datasheetดูเหมือนขยะ ต้องดูในโหมด HEX และต้องมี datasheet (ลำดับไบต์, endianness, scale)
ขนาดยาว: “+ 100.0 g” ใช้ 9 ไบต์กะทัดรัด: 2 ไบต์เก็บ 0–65,535
เหมาะกับDebug, อุปกรณ์ที่คนอ่านLoRa (payload ≈ 50 ไบต์) — กลุ่ม LoRa ควรใช้ binary

เฟรมเดียว สามชั้นกายภาพ

TTLRS-232RS-485
Logic 13.3 V (หรือ 5 V)−3 ถึง −15 VA − B < −200 mV
Logic 00 V+3 ถึง +15 VA − B > +200 mV
สาย1 เส้นต่อทิศ + GND1 เส้นต่อทิศ + GNDคู่ A/B ใช้ร่วม + GND
ระยะจริง~1 m~15 m~1,200 m
หลายอุปกรณ์บนสายเดียวไม่ได้ไม่ได้ได้ (Modbus)
ต่อตรงกับ ESP32ได้ (3.3 V)ไม่ได้ ขาพังไม่ได้ ต้องผ่าน MAX485
ในรายวิชาGPS M8N, ultrasonicตาชั่งของภาควิชาXY-MD02, S-Soil MT-02, S700-B

ชิปแปลง MAX3232 (TTL↔RS-232) และ MAX485 (TTL↔RS-485) เปลี่ยนเฉพาะชั้นกายภาพ เฟรมและ baud rate คงเดิม

ESP32 ทนได้สูงสุด 3.6 V และรับแรงดันลบไม่ได้ ห้ามต่อสาย RS-232 ของตาชั่งเข้า GPIO โดยตรง (Activity 4.0 จะให้ดูสัญญาณบนออสซิลโลสโคปก่อน)

RS-485: สัญญาณแบบ differential

สัญญาณ RS-485 ขณะส่งอักขระ 0xD3: สาย U+ และ U− กลับเฟสกันเสมอ ตัวรับอ่านผลต่างระหว่างสองสาย
รูปที่ 3.9 สัญญาณ RS-485 ขณะส่งอักขระ 0xD3: สาย U+ และ U− กลับเฟสกันเสมอ ตัวรับอ่านผลต่างระหว่างสองสาย ภาพ: Roy Vegard Ovesen / Wikimedia Commons, CC BY-SA 3.0

Modbus RTU

Master ตัวเดียวเป็นผู้ถาม slave ตอบเมื่อถูกเรียกเท่านั้น slave address (1–247) ผู้ใช้เป็นผู้ตั้ง[7]

Function codeชื่อใช้กับ
0x03Read Holding Registers (อ่าน/เขียนได้)ค่าตั้งของอุปกรณ์ เช่น address, baud rate
0x04Read Input Registers (อ่านอย่างเดียว)ค่าที่วัดได้ — XY-MD02 เก็บอุณหภูมิและความชื้นที่ 0x0001–0x0002
0x06Write Single Registerเปลี่ยน address ของ slave
Slave สองตัวที่มี address ซ้ำกันบนสายเดียวจะตอบพร้อมกันและชนกัน — ตั้ง address ของเซนเซอร์ใหม่ทีละตัวก่อนต่อเข้าสาย

3.9I²C และ SPI

I²C: bus สองสายสำหรับหลายอุปกรณ์

3.3 V ESP32 master SDA SCL OLED 0x3C Ultrasonic 0x57
รูปที่ 3.10 I²C bus: อุปกรณ์ทุกตัวใช้ SDA/SCL ร่วมกัน โดยมีตัวต้านทาน pull-up ดึงสายขึ้น 3.3 V

หนึ่ง transaction: Wire.requestFrom(0x57, 3) สร้างลำดับบนสายดังนี้ START → address + บิต R → slave ส่ง 3 ไบต์ตาม clock ของ master → master ตอบ ACK ทุกไบต์ยกเว้นไบต์สุดท้ายตอบ NACK → STOP ส่วน I²C scanner ก็แค่ลองส่ง START + address + W ไปที่ 1–127 แล้วดูว่า address ใดตอบ ACK

ลำดับการส่งข้อมูลบน I²C: เงื่อนไข START (S) ข้อมูลแต่ละบิต B1…BN ที่อ่านขณะ SCL สูง และเงื่อนไข STOP (P)
รูปที่ 3.11 ลำดับการส่งข้อมูลบน I²C: เงื่อนไข START (S) ข้อมูลแต่ละบิต B1…BN ที่อ่านขณะ SCL สูง และเงื่อนไข STOP (P) ภาพ: Marcin Floryan / Wikimedia Commons, Public domain

SPI: เร็วที่สุด หนึ่ง CS ต่ออุปกรณ์

SPI master หนึ่งตัวกับ slave สามตัว: สาย SCLK, MOSI, MISO ใช้ร่วมกัน แต่ละ slave มีสาย SS (CS) ของตัวเอง
รูปที่ 3.12 SPI master หนึ่งตัวกับ slave สามตัว: สาย SCLK, MOSI, MISO ใช้ร่วมกัน แต่ละ slave มีสาย SS (CS) ของตัวเอง ภาพ: Cburnett / Wikimedia Commons, CC BY-SA 3.0

อ่าน MAX6675[8]: ชิปไม่มี register และไม่มีคำสั่ง แค่ดึง CS ลง ให้ clock 16 ครั้ง ก็จะได้ 16 บิตกลับมา

digitalWrite(CS, LOW);              // เลือกชิป เริ่มส่งบิต D15 ทาง MISO
uint16_t w = SPI.transfer16(0);     // 16 clock: MOSI ส่ง 0 (ชิปไม่สนใจ), MISO รับ 16 บิต
digitalWrite(CS, HIGH);             // ปล่อยชิป เริ่มแปลงค่าใหม่ (~220 ms)

bool open = w & 0x0004;             // บิต 2 = thermocouple ขาด
float T = ((w >> 3) & 0x0FFF) * 0.25;  // เลื่อนขวา 3 บิต เก็บ 12 บิต × 0.25 °C/LSB

MAX31865 (PT100)[9] ซับซ้อนกว่าเล็กน้อย: เขียน configuration register ก่อน แล้วอ่าน RTD register 2 ไบต์ — รูปแบบเดิมคือ CS ลง → ส่ง address → รับข้อมูล → CS ขึ้น

3.101-Wire และ CAN bus

1-Wire: สายเดียว ID 64 บิต

DS18B20 ในตัวถัง TO-92 เทียบขนาดกับเหรียญ (สามขา: GND, DQ, VDD)
รูปที่ 3.13 DS18B20 ในตัวถัง TO-92 เทียบขนาดกับเหรียญ (สามขา: GND, DQ, VDD) ภาพ: SparkFun Electronics / Wikimedia Commons, CC BY 2.0
DS18B20 resolutionขั้นเวลาแปลง
9 บิต0.5 °C94 ms
10 บิต0.25 °C188 ms
11 บิต0.125 °C375 ms
12 บิต0.0625 °C750 ms

CAN bus

โครงสร้างเฟรมข้อมูล CAN แบบ base (2.0A): start of frame, identifier 11 บิต, control/DLC, data 0–64 บิต, CRC, ACK และ end of frame
รูปที่ 3.14 โครงสร้างเฟรมข้อมูล CAN แบบ base (2.0A): start of frame, identifier 11 บิต, control/DLC, data 0–64 บิต, CRC, ACK และ end of frame ภาพ: Fröstel (S.G.) / Wikimedia Commons, CC0
Modbus หลีกเลี่ยงการชนด้วยการให้ master ถามทีละตัว (เหมาะกับเซนเซอร์ช้า) ส่วน CAN หลีกเลี่ยงด้วยลำดับความสำคัญ (เหมาะกับเครื่องจักรที่มีหลายตัวควบคุม)

3.11การเลือก Interface

InterfaceสายAddressClockระยะใช้กับ
GPIO / timing1–2ไม่มีโค้ดผู้ใช้< 1 mHC-SR04 trig/echo, พัลส์ flow, รีเลย์
ADC (อนาล็อก)1ไม่มีผู้ใช้สั่งอ่านสั้นที่สุดNTC, LDR, MPX5010DP, capacitive
UART TTL2 (TX/RX)ไม่มี (1:1)ตกลง baud~1 mGPS M8N, ultrasonic โหมด UART
UART RS-2322 + GNDไม่มีตกลง baud~15 mตาชั่งของภาควิชา
RS-485 / Modbus2 differentialผู้ใช้ตั้งmaster ถาม slave ตอบ~1,200 mXY-MD02, S-Soil MT-02, S700-B
I²C2 (SDA/SCL)7 บิต ผู้ผลิตตั้งmaster< 1 mOLED 0x3C, ultrasonic 0x57
SPI4 (SCK/MOSI/MISO/CS)ไม่มี ใช้ CSmaster เร็วสุด< 30 cmMAX6675, MAX31865, microSD
1-Wire1 + GNDROM 64 บิตจากโรงงานmaster, µsหลายสิบ mDS18B20
CAN2 differentialmessage IDmulti-master40 m @ 1 Mbit/sรถแทรกเตอร์, ISOBUS
① Address แยก bus ออกจาก point-to-point: RS-485, I²C, 1-Wire ต่อหลายตัวได้ ส่วน UART TTL ไม่ได้ · SPI ใช้ CS แทน address (เร็วแต่ใช้ขามาก)
② ที่มาของ address ต่างกัน: ผู้ใช้ตั้ง (Modbus), ผู้ผลิตตั้ง (I²C), ฝังจากโรงงาน (1-Wire)
③ ระยะเป็นเรื่องชั้นกายภาพ: SPI และ I²C เร็วแต่สั้น ส่วน RS-485 และ 1-Wire ออกแบบมาสำหรับสายยาวในภาคสนาม

Lab 4: Digital Signals with ESP32

กิจกรรมInterfaceสิ่งที่จะเห็น/ทำ
4.0 ตาชั่ง RS-232 (สาธิต)UART / RS-232สัญญาณ ±12 V บนออสซิลโลสโคป, ข้อความ ASCII, สถานะ ST/US
4.1 ESP32 ADCADC, attenuationสอบเทียบ 6 จุดเทียบมัลติมิเตอร์ หา m, c ของ V = m·count + c
4.2 GPS fix qualityUART / TTLตรวจคุณภาพ fix ก่อนใช้ตำแหน่ง
4.3 Ultrasonic โหมด UARTUART / binaryถอดรหัสไบต์ด้วยมือจาก logic analyzer
4.4 Ultrasonic I²C + OLEDI²CScan พบ 0x3C และ 0x57 และดู transaction บนสาย
4.5 XY-MD02RS-485 / Modbusสัญญาณ differential และเฟรม request/response
4.8 Relay + deadbandGPIOก้าวแรกจากการวัดสู่การควบคุม

เตรียมก่อนแล็บ: ติดตั้ง Arduino IDE + ESP32 board package + ไดรเวอร์ CP2102/CH340 · รัน Blink บน ESP32 DevKit แล้วส่งภาพหน้าจอ · อ่านหัวข้อ UART, Modbus, I²C, SPI, 1-Wire และตารางการเลือก interface

✎แบบฝึกหัดท้ายบท

ตอนที่ 1: ปรนัยและเติมตัวเลข

โครงงานใช้ WiFi ส่งข้อมูล ควรต่อเซนเซอร์อนาล็อกเข้าขาใดของ ESP32?

SAR ADC ขนาด 10 บิต ใช้กี่ขั้นในการแปลงหนึ่งครั้ง?

ตั้ง baud rate ของ ESP32 ไม่ตรงกับ GPS จะเกิดอะไรขึ้น?

สาย RS-485 ยาว 200 m มีเซนเซอร์ 4 ตัว ควรติด terminator 120 Ω ที่ใด?

Address ของอุปกรณ์ 1-Wire (เช่น DS18B20) มาจากไหน?

ต้องการอ่าน load cell ที่ให้สัญญาณระดับ mV ด้วยความละเอียดสูง ควรเลือก ADC แบบใด?

ESP32 อ่านค่า 4095 จากเซนเซอร์ที่ตั้ง attenuation 6 dB ข้อสรุปใดถูกต้อง?

ADC 10 บิตที่ Vref = 5 V มีความละเอียด (1 LSB) เท่าใด?

mV

Flash ADC ขนาด 8 บิต ต้องใช้ comparator กี่ตัว?

ตัว

Modbus register ของเซนเซอร์อุณหภูมิอ่านได้ 0x00FA และมี scale ÷10 อุณหภูมิเท่าใด?

°C

MAX6675 ส่งค่า w = 0x0C80 มา อุณหภูมิเท่าใด? (T = ((w >> 3) & 0x0FFF) × 0.25)

°C

ESP32 ตั้ง attenuation 6 dB ช่วงเต็มสเกลของอินพุตประมาณเท่าใด? (Vref = 1.1 V)

V

ตอนที่ 2: โจทย์คำนวณพร้อมเฉลย

โจทย์ 1 — ไล่ขั้นตอน SAR ADC

SAR ADC 4 บิต, Vref = 10 V, Vin = 6.8 V จงแสดงแต่ละขั้นและหาผลลัพธ์

ขั้นละ 10/16 = 0.625 V

ขั้นรหัสVDACผล
i = 310008 × 0.625 = 5.000 V < 6.8คง b3
i = 2110012 × 0.625 = 7.500 V > 6.8ล้าง b2
i = 1101010 × 0.625 = 6.250 V < 6.8คง b1
i = 0101111 × 0.625 = 6.875 V > 6.8ล้าง b0

ผลลัพธ์ 10102 = 10 → 6.25 V (ต่ำกว่าค่าจริง 0.55 V ซึ่งน้อยกว่า 1 LSB)

โจทย์ 2 — สอบเทียบ ADC ของ ESP32 (แนว Activity 4.1)

ที่ attenuation 11 dB วัดด้วยมัลติมิเตอร์ได้ 0.50 V ขณะ ADC อ่านได้ 480 และ 2.00 V ขณะอ่านได้ 2340 จงหาสมการ V = m·count + c แล้วคำนวณแรงดันเมื่ออ่านได้ 1500

m = (2.00 − 0.50)/(2340 − 480) = 1.50/1860 = 0.000806 V/count

c = 0.50 − 0.000806 × 480 = 0.50 − 0.387 = 0.113 V

ที่ count 1500: V = 0.000806 × 1500 + 0.113 ≈ 1.32 V

ในแล็บจริงใช้ 6 จุดแล้ว fit ด้วย least squares และหลีกเลี่ยงช่วงต่ำกว่า 0.15 V และสูงกว่า 2.45 V ที่ไม่เป็นเชิงเส้น

โจทย์ 3 — เลือก interface สำหรับ soil node

Soil node ต้องอ่าน (ก) เซนเซอร์ความชื้นดินที่อยู่ห่าง 30 m (ข) อุณหภูมิดิน 3 ระดับความลึก (ค) จอ OLED บนกล่องเดียวกัน จงเลือก interface และให้เหตุผล

(ก) RS-485 / Modbus — สัญญาณ differential ทนสัญญาณรบกวนจากปั๊มในระยะหลายสิบเมตร ถ้าใช้อนาล็อกสาย 30 m จะรับสัญญาณรบกวนมาก

(ข) 1-Wire (DS18B20 × 3) — ต่อบนสายเดียวแบบ daisy chain แต่ละตัวมี ROM ID ไม่ซ้ำ จึงแยกแต่ละความลึกได้

(ค) I²C — อยู่บนบอร์ดเดียวกัน ระยะสั้น ใช้แค่สองสาย และต่ออุปกรณ์อื่นบน bus เดียวกันได้

โจทย์ 4 — ASCII หรือ Binary สำหรับ LoRa

Node ต้องส่งอุณหภูมิ (−10.0 ถึง 60.0 °C) ความชื้นดิน (0.0–100.0%) และแรงดันแบตเตอรี่ (0.00–5.00 V) ผ่าน LoRa จงเปรียบเทียบขนาด payload แบบ ASCII กับ binary

ASCII เช่น "-10.0,100.0,4.20" ใช้ประมาณ 16 ไบต์

Binary: เก็บแต่ละค่าเป็นจำนวนเต็ม 16 บิต (×10, ×10, ×100) → อุณหภูมิ −100…600, ความชื้น 0…1000, แรงดัน 0…500 ใช้ 3 × 2 = 6 ไบต์

Binary เล็กกว่าเกือบ 3 เท่า ส่งได้เร็วขึ้นและประหยัดพลังงาน แต่ผู้รับต้องรู้ลำดับไบต์ endianness และ scale — ต้องเขียนเป็นเอกสารร่วมกันทุกกลุ่ม

§แหล่งอ้างอิง

เอกสาร

  1. Udompetaikul, V. (2026). INS03: Digital Signals (v9) [เอกสารประกอบการสอน]. รายวิชา 01386309 Agricultural Instrumentation & IoT, สถาบันเทคโนโลยีพระจอมเกล้าเจ้าคุณทหารลาดกระบัง.
  2. Espressif Systems. ESP-IDF Programming Guide v4.4 — Analog to Digital Converter (ADC). https://docs.espressif.com/projects/esp-idf/en/v4.4/esp32/api-reference/peripherals/adc.html
  3. Espressif Systems. ESP32 Series Datasheet. https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf
  4. Llamas, L. How to use the ADC analog inputs in an ESP32. luisllamas.es. https://www.luisllamas.es/en/esp32-adc/
  5. Monk, S. (2024). ผลการวัด ADC ของ ESP32 ที่ attenuation 0 dB, Doctor Monk’s DIY Electronics Blog — อ้างถึงใน [1]. https://doctormonk.com/
  6. Kuphaldt, T. R. Lessons in Electric Circuits, Vol. IV — Digital, Chapter 13: Digital-Analog Conversion. All About Circuits. https://www.allaboutcircuits.com/textbook/digital/chpt-13/
  7. Modbus Organization. (2012). MODBUS Application Protocol Specification V1.1b3. https://www.modbus.org/file/secure/modbusprotocolspecification.pdf
  8. Analog Devices (Maxim Integrated). MAX6675 — Cold-junction-compensated K-thermocouple-to-digital converter. https://www.analog.com/en/products/max6675.html
  9. Analog Devices (Maxim Integrated). MAX31865 — RTD-to-digital converter. https://www.analog.com/en/products/max31865.html
  10. Analog Devices (Maxim Integrated). DS18B20 — Programmable resolution 1-Wire digital thermometer. https://www.analog.com/en/products/ds18b20.html

รูปประกอบ

รูปจาก Wikimedia Commons ใช้ตามสัญญาอนุญาตที่ระบุ โดยไม่ได้ดัดแปลงนอกจากย่อขนาด ส่วนรูปวงจรและกราฟที่ไม่มีเครดิตจัดทำขึ้นใหม่สำหรับสื่อการสอนนี้