🧩 1. ความหมายของ Analog Signal

สัญญาณแอนะล็อก (Analog Signal) คือสัญญาณที่มีค่าต่อเนื่อง สามารถมีค่าได้ทุกค่าระหว่าง 0 ถึงค่ามากสุด เช่น 0–3.3V

ตัวอย่างสัญญาณแอนะล็อกในชีวิตจริง:

  • อุณหภูมิจากเซนเซอร์ LM35
  • ความเข้มแสงจาก LDR
  • เสียงจากไมค์
  • แรงดันไฟจากแบตเตอรี่

เมื่อไมโครคอนโทรลเลอร์ต้องการ “อ่าน” ค่านี้ จะต้องแปลงเป็น “ตัวเลขดิจิทัล”
โดยใช้วงจรที่เรียกว่า ADC (Analog-to-Digital Converter)


⚙️ 2. Analog Input (การอ่านค่าแอนะล็อก)

🔸 Arduino UNO

  • ใช้ขา A0–A5 (6 ช่องสัญญาณ)
  • ความละเอียด 10-bit → อ่านค่าได้ 0–1023
  • แรงดันอ้างอิง (Vref) = 5V หรือ 3.3V

🔸 ESP32

  • มี ADC 2 ตัว: ADC1 และ ADC2
  • ขา ADC1: GPIO 32–39
  • ความละเอียด 12-bit → 0–4095
  • แรงดันอ้างอิง = 3.3V

หมายความว่า แรงดัน 3.3V = ค่า 4095


🔹 3. การอ่านค่า Analog Input

คำสั่งพื้นฐาน:

C++
analogRead(pin);

📘 ตัวอย่าง:

C++
const int sensorPin = 34; // LDR ต่อที่ขา 34

void setup() {
  Serial.begin(115200);
}

void loop() {
  int raw = analogRead(sensorPin);
  Serial.println(raw);
  delay(500);
}

🔹 4. การแปลงค่า ADC → แรงดัน (Voltage)

สมการทั่วไป: V=(ADC_Value/Max_ADC)×VrefV = (ADC\_Value / Max\_ADC) \times V_{ref}V=(ADC_Value/Max_ADC)×Vref​

สำหรับ ESP32: V=ADC×3.34095.0V = ADC \times \frac{3.3}{4095.0}V=ADC×4095.03.3​

📘 ตัวอย่าง:

C++
int adc = analogRead(34);
float voltage = (float)adc * 3.3 / 4095.0;
Serial.printf("ADC = %d, Voltage = %.2f V\n", adc, voltage);

🔹 5. การอ่านค่า Sensor (ตัวอย่าง LM35)

LM35 ให้แรงดัน 10 mV ต่อ 1°C
ดังนั้นถ้าอ่านได้ 1.0V → 100°C

📘 ตัวอย่าง:

C++
int val = analogRead(34);
float volt = val * 3.3 / 4095.0;
float tempC = volt * 100.0;
Serial.printf("Temp = %.2f °C\n", tempC);

🔹 6. การอ่านค่า LDR (Light Sensor)

ต่อแบบตัวแบ่งแรงดัน (Voltage Divider)

📘 ตัวอย่าง:

C++
int ldr = analogRead(34);
float brightness = map(ldr, 0, 4095, 0, 100);
Serial.printf("Brightness = %.0f%%\n", brightness);

คำสั่ง map() ใช้แปลงช่วงค่า เช่น จาก 0–4095 → 0–100%


🔹 7. การแปลงช่วงค่า (Scaling)

ฟังก์ชัน map() ใช้ในการแปลงช่วงตัวเลข

C++
map(value, fromLow, fromHigh, toLow, toHigh)

📘 ตัวอย่าง:

C++
int adc = analogRead(34);
int pwm = map(adc, 0, 4095, 0, 255); // แปลงเป็นค่า PWM
analogWrite(2, pwm);

🔹 8. Noise และการกรองค่า (Smoothing)

สัญญาณ Analog มักมี Noise → ควรเฉลี่ยค่า

📘 ตัวอย่าง:

C++
int readAverage(int pin) {
  long sum = 0;
  for (int i = 0; i < 10; i++) {
    sum += analogRead(pin);
    delay(5);
  }
  return sum / 10;
}

⚡ 9. Analog Output (PWM / DAC)

ไมโครคอนโทรลเลอร์ไม่สามารถ “ส่งแรงดันต่อเนื่องจริง” ได้ทุกขา
จึงใช้เทคนิค PWM (Pulse Width Modulation) เพื่อจำลองสัญญาณแอนะล็อก


🔹 9.1 PWM (Pulse Width Modulation)

คือการสลับสัญญาณ HIGH/LOW ด้วยความเร็วสูง
และควบคุม อัตราส่วนเวลาที่เป็น HIGH (Duty Cycle)
→ เพื่อจำลองระดับแรงดันเฉลี่ย

ค่า PWMDuty Cycleแรงดันจำลอง (3.3V)
00%0V
12850%1.65V
255100%3.3V

📘 Arduino:

C++
analogWrite(9, 128); // ครึ่งแรงดัน (2.5V)

📘 ESP32:

C++
const int led = 2;
void setup() {
  ledcSetup(0, 5000, 8);  // channel 0, freq 5kHz, resolution 8-bit
  ledcAttachPin(led, 0);
}

void loop() {
  for (int i = 0; i <= 255; i++) {
    ledcWrite(0, i);
    delay(5);
  }
  for (int i = 255; i >= 0; i--) {
    ledcWrite(0, i);
    delay(5);
  }
}

ใช้ PWM ได้ทุกขาใน ESP32 และเลือกความละเอียดได้ถึง 16-bit


🔹 9.2 DAC (Digital to Analog Converter)

ESP32 มี DAC จริง 2 ช่อง: GPIO25 และ GPIO26
สามารถสร้างแรงดัน 0–3.3V ต่อเนื่องจริง (ไม่ใช่ PWM)

คำสั่งความหมาย
dacWrite(pin, value)สร้างแรงดัน 0–255 (8-bit)

📘 ตัวอย่าง:

C++
for (int i=0; i<=255; i++) {
  dacWrite(25, i);
  delay(10);
}

ใช้ได้เฉพาะขา GPIO25, GPIO26 เท่านั้น


🔹 10. การเปรียบเทียบ PWM vs DAC

รายการPWM (จำลอง)DAC (จริง)
หลักการเปิด–ปิดเร็วมากแปลงเป็นแรงดันจริง
ความละเอียด8–16 bit (ตั้งได้)8 bit
ขาใช้งานได้เกือบทุกขาเฉพาะ 25, 26
ใช้ควบคุมLED, Servo, Motorเสียง, สัญญาณ Audio
ความแม่นยำต่ำกว่า DACสูงกว่า

🔹 11. ตัวอย่าง: อ่าน Analog แล้วส่ง PWM ออก

📘 ตัวอย่าง: “หมุนปุ่ม Potentiometer → ปรับความสว่าง LED”

C++
int pot = 34;
int led = 2;

void setup() {
  ledcSetup(0, 5000, 8);
  ledcAttachPin(led, 0);
}

void loop() {
  int val = analogRead(pot);
  int pwm = map(val, 0, 4095, 0, 255);
  ledcWrite(0, pwm);
}

🔹 12. ตัวอย่าง: DAC สร้างคลื่นไซน์ (ESP32 เท่านั้น)

C++
#include <math.h>
const int dacPin = 25;

void setup() {}

void loop() {
  for (int i=0; i<360; i++) {
    int val = 128 + 127 * sin(i * 3.14 / 180); // 0–255
    dacWrite(dacPin, val);
    delayMicroseconds(100);
  }
}

จะได้คลื่นสัญญาณต่อเนื่อง (Analog waveform) ออกทางขา 25


📚 13. แบบฝึกหัด

1️⃣ อ่านค่า ADC จาก LDR แล้วพิมพ์แรงดันออกทาง Serial
2️⃣ อ่านค่า Potentiometer แล้วควบคุมความสว่าง LED (PWM)
3️⃣ อ่านค่า LM35 แล้วคำนวณอุณหภูมิ °C
4️⃣ เขียนฟังก์ชันเฉลี่ยค่า ADC 10 ครั้ง (Noise Filter)
5️⃣ ใช้ DAC ของ ESP32 สร้างคลื่นสามเหลี่ยม (0–3.3V)


🧾 14. สรุป

หัวข้อคำอธิบาย
Analog Inputอ่านค่าแรงดันต่อเนื่องผ่าน ADC
Analog Outputสร้างแรงดันต่อเนื่อง (PWM หรือ DAC)
ADC (Analog → Digital)แปลงแรงดันเป็นตัวเลข 0–1023 / 0–4095
DAC (Digital → Analog)แปลงตัวเลขเป็นแรงดันจริง (เฉพาะขา 25,26)
PWMจำลองแรงดันด้วยคลื่น duty cycle
Resolutionความละเอียดของการวัด เช่น 10-bit = 1024 ระดับ
map()ฟังก์ชันแปลงช่วงค่า
Noise Filteringอ่านหลายครั้งแล้วเฉลี่ยเพื่อความเสถียร
ใช้จริงเซนเซอร์, ปรับความสว่าง, ควบคุมเสียง/มอเตอร์