🧩 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
คำสั่งพื้นฐาน:
analogRead(pin);
📘 ตัวอย่าง:
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
📘 ตัวอย่าง:
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
📘 ตัวอย่าง:
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)
📘 ตัวอย่าง:
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() ใช้ในการแปลงช่วงตัวเลข
map(value, fromLow, fromHigh, toLow, toHigh)
📘 ตัวอย่าง:
int adc = analogRead(34);
int pwm = map(adc, 0, 4095, 0, 255); // แปลงเป็นค่า PWM
analogWrite(2, pwm);
🔹 8. Noise และการกรองค่า (Smoothing)
สัญญาณ Analog มักมี Noise → ควรเฉลี่ยค่า
📘 ตัวอย่าง:
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)
→ เพื่อจำลองระดับแรงดันเฉลี่ย
| ค่า PWM | Duty Cycle | แรงดันจำลอง (3.3V) |
|---|---|---|
| 0 | 0% | 0V |
| 128 | 50% | 1.65V |
| 255 | 100% | 3.3V |
📘 Arduino:
analogWrite(9, 128); // ครึ่งแรงดัน (2.5V)
📘 ESP32:
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) |
📘 ตัวอย่าง:
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”
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 เท่านั้น)
#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 | อ่านหลายครั้งแล้วเฉลี่ยเพื่อความเสถียร |
| ใช้จริง | เซนเซอร์, ปรับความสว่าง, ควบคุมเสียง/มอเตอร์ |
