ADS1115 เป็น ADC ภายนอก 16 บิตที่ ESP32 อ่านผ่าน I2C ได้ ในบทความนี้จะเลี้ยง ADS1115 ด้วย 3.3V ต่อ SDA กับ GPIO21 และ SCL กับ GPIO22 ตั้ง ADDR ลง GND เพื่อใช้ address 0x48 แล้วใช้ตัวต้านทานปรับค่าได้ 10kΩ ทดสอบ A0 ก่อนต่อเซนเซอร์จริง
เคยต่อเซนเซอร์ Analog กับ ESP32 แล้วอ่านค่ากระโดด หรือสงสัยว่าค่าที่เห็นใน Serial Monitor แปลงเป็นแรงดันเท่าไรกันแน่ไหม? บทความนี้เราจะเริ่มจากวงจรที่ตรวจสอบได้ด้วยมัลติมิเตอร์ แทนการเริ่มจากเซนเซอร์ pH/EC ที่มีตัวแปรเรื่องการสอบเทียบเข้ามาเกี่ยวข้อง
ผมจะพาต่อ ADS1115 เข้ากับ ESP32 DevKit V1 ผ่าน I2C ตั้งค่า Gain เขียนโค้ดใน PlatformIO อ่านค่า Raw ADC และ Voltage แล้วอธิบายวิธีตรวจสอบก่อนนำไปใช้ในโครงงาน Smart Farm ภาพประกอบส่วนหนึ่งมาจากการทดลองจริงที่เจ้าของเว็บถ่ายไว้ แต่ยังไม่ได้ตรวจผล Build/Upload หรือค่าที่วัดเทียบมัลติมิเตอร์ซ้ำอย่างอิสระ จึงแยกผลที่คาดว่าจะเห็นจากผลทดสอบจริงให้ชัดเจน
ADS1115 คืออะไร? ทำไมใช้กับ ESP32
ADS1115 ของ Texas Instruments เป็น ADC แบบ Delta-Sigma ความละเอียด 16 บิต ใช้บัส I2C มี Programmable Gain Amplifier (PGA) ปรับช่วงการวัดได้ และเลือกอ่าน 4 ช่อง Single-ended (A0–A3) หรือ 2 คู่ Differential ผ่าน Multiplexer ภายใน โดยไม่ได้วัด 4 ช่องพร้อมกัน
ค่าดิจิทัลแบบ signed
อินพุต Single-ended 4 ช่อง
ใช้สาย SDA/SCL สองเส้น
อัตราแปลงสัญญาณตามที่เลือก
อย่าเพิ่งสรุปว่า ADC 16 บิตเท่ากับความแม่นยำของเครื่องวัด 16 บิต เพราะคุณภาพแหล่งจ่าย Noise วงจรขยายสัญญาณ การเดินสาย และ Calibration ยังส่งผลต่อค่าที่อ่านได้ อ่านสเปก ADS1115 จาก TI
ADS1115 ต่างจาก ADC ภายใน ESP32 อย่างไร?
| ประเด็น | ADC ของ ESP32 รุ่นดั้งเดิม | ADS1115 ภายนอก |
|---|---|---|
| ความละเอียดทั่วไป | 12 บิต | 16 บิต signed |
| วิธีอ่าน | ขา ADC ภายใน | ผ่านบัส I2C |
| ช่องอินพุต | ขึ้นกับรุ่น/กลุ่ม ADC1 ADC2 | 4 ช่อง Single-ended หรือ 2 คู่ Differential |
| ช่วงแรงดัน | ขึ้นกับ Attenuation และ Calibration | ตั้ง PGA ได้ แต่แรงดันขาเข้ายังจำกัดด้วย VDD |
| เหมาะกับงาน | อ่าน Analog ทั่วไป | ต้องการ ADC แยก ปรับช่วงวัดได้ และจัดการช่องสัญญาณชัดเจน |
ถ้าไม่คุ้นกับ Raw ADC และแรงดัน อ่าน พื้นฐาน ADC ของ ESP32 ก่อน ส่วนตำแหน่ง GPIO ดู ESP32 DevKit V1 Pinout
อุปกรณ์และผังต่อสาย ADS1115 กับ ESP32
ใช้ ESP32 ได้ทั้งรุ่นพอร์ต Micro-USB และ USB-C เลือกสายที่รองรับการส่งข้อมูลและตรงกับพอร์ตของบอร์ด ลิงก์สายด้านล่างเป็นรุ่น Micro-USB
บทความนี้มีลิงก์ Affiliate เว็บไซต์อาจได้รับค่าคอมมิชชันเมื่อซื้อผ่านลิงก์
- บอร์ดทดลอง MB-102 / GL-12 บน Shopee
- โมดูล ADS1115 บน Shopee
- บอร์ด ESP32 ESP-WROOM-32 บน Shopee
- ตัวต้านทานปรับค่าได้ WH148 เลือก B10K บน Shopee
- สายจัมเปอร์ บน Shopee
- สายส่งข้อมูล USB-A → Micro-USB บน Shopee
- มัลติมิเตอร์ UNI-T UT33D+ บน Shopee
เตรียม ESP32 DevKit V1, ADS1115 Breakout, VR 10kΩ, Breadboard, Jumper, สาย USB และมัลติมิเตอร์สำหรับวัดแรงดัน โดยตรวจชื่อขาจากบอร์ดจริงก่อนเสียบสาย เพราะตำแหน่งขาแต่ละผู้ผลิตอาจไม่เรียงเหมือนกัน

| ESP32 / อุปกรณ์ | ADS1115 | หน้าที่ |
|---|---|---|
| 3V3 | VDD | ไฟเลี้ยง 3.3V |
| GND | GND | กราวด์ร่วม |
| GPIO21 | SDA | I2C Data |
| GPIO22 | SCL | I2C Clock |
| GND | ADDR | ตั้ง Address 0x48 |
| ขากลาง VR 10kΩ | A0 / AIN0 | แรงดันทดสอบ |
| ปลาย VR ด้านหนึ่งไป 3V3 อีกด้านไป GND | — | ปรับช่วงใกล้ 0–3.3V |
โมดูล ADS1115 บางรุ่นมีตัวต้านทาน Pull-up SDA/SCL ติดมาแล้ว ตรวจให้แน่ใจว่าดึงขึ้นไปที่ 3.3V ไม่ใช่ 5V ก่อนต่อกับ ESP32
เมื่อ ADDR ต่อ GND จะได้ I2C Address 0x48; หากต่อ VDD จะเป็น 0x49, SDA เป็น 0x4A และ SCL เป็น 0x4B ตามการกำหนดแอดเดรสของชิป
เลือก Gain/PGA อย่างไร ไม่ให้เข้าใจช่วงแรงดันผิด
สำหรับวงจรที่ ADS1115 ใช้ไฟเลี้ยง VDD = 3.3V เราจะตั้ง Gain ในไลบรารี Adafruit เพื่อกำหนด Full-scale Range (FSR) ของ ADC แต่ FSR ไม่ได้เปลี่ยนขีดจำกัดแรงดันไฟฟ้าจริงที่ขา A0–A3
| Adafruit Gain | Full-scale Range | แรงดันต่อ 1 Count (ประมาณ) |
|---|---|---|
GAIN_TWOTHIRDS | ±6.144V | 187.5 µV |
GAIN_ONE | ±4.096V | 125 µV |
GAIN_TWO | ±2.048V | 62.5 µV |
GAIN_FOUR | ±1.024V | 31.25 µV |
เมื่อชิปใช้ไฟเลี้ยง 3.3V ให้รักษาแรงดัน Single-ended A0–A3 ภายในช่วง GND ถึง VDD (0–3.3V) ตามช่วงทำงานที่แนะนำ ห้ามป้อน 4.096V, 5V หรือแรงดันติดลบเข้าขาอินพุตเพียงเพราะ PGA แสดงช่วง ±4.096V
ตัวอย่างทดสอบด้วย VR หมุนได้ใกล้ 0–3.3V จึงเริ่มที่ GAIN_ONE เพราะ FSR ±4.096V ครอบคลุมช่วงนี้ ถ้าเซนเซอร์ยืนยันแล้วว่าแรงดันสูงสุดไม่ถึง 2.048V จึงค่อยพิจารณา GAIN_TWO เพื่อให้ความละเอียดต่อ Count เล็กลง
ตัวอย่างเชิงคำนวณ: เมื่อใช้ GAIN_ONE ค่า Raw ADC = 12000 จะเท่ากับ 12000 × 0.000125 ≈ 1.5000V ตัวเลขนี้เป็นตัวอย่างการคิด ไม่ใช่ผลวัดจริงจากวงจรในบทความ
สร้างโปรเจกต์ VS Code + PlatformIO
- เปิด VS Code และ PlatformIO แล้วสร้างโปรเจกต์ใหม่ เลือกบอร์ด Espressif ESP32 Dev Module และ Framework เป็น Arduino
- กำหนดไฟล์
platformio.iniเพื่อเรียกใช้ไลบรารี Adafruit ADS1X15 - เขียนโค้ดลง
src/main.cppโดยอ่าน A0 ช่องเดียวก่อน - เมื่อเช็กวงจรและไฟเลี้ยงแล้วจึง Build, Upload และเปิด Serial Monitor ที่ 115200 baud

platformio.ini
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps =
adafruit/Adafruit ADS1X15สำหรับโปรเจกต์ใช้งานจริงควรล็อกเวอร์ชันของแพลตฟอร์มและไลบรารีหลังจากตรวจ Build ผ่านจริงแล้ว เพื่อให้คนเรียนติดตั้ง dependency ตรงกัน
โค้ด ESP32 อ่านค่า Analog จาก ADS1115 ผ่าน I2C
ตัวอย่างนี้ใช้คลาส Adafruit_ADS1115 สำหรับ 16 บิต โดยอ่าน A0 ผ่าน readADC_SingleEnded(0) และแปลง Raw เป็นแรงดันด้วย computeVolts()
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_ADS1X15.h>
constexpr int I2C_SDA = 21;
constexpr int I2C_SCL = 22;
constexpr uint8_t ADS_ADDR = 0x48;
constexpr bool READ_A1 = false;
Adafruit_ADS1115 ads;
void setup() {
Serial.begin(115200);
delay(500);
Wire.begin(I2C_SDA, I2C_SCL);
Wire.setClock(100000);
if (!ads.begin(ADS_ADDR, &Wire)) {
Serial.println("ADS1115 not found. Check wiring.");
while (true) {
delay(1000);
}
}
// FSR +/-4.096 V; physical input must stay within GND..VDD.
ads.setGain(GAIN_ONE);
ads.setDataRate(RATE_ADS1115_128SPS);
Serial.println("ADS1115 ready. Turn VR at A0.");
}
void loop() {
int16_t rawA0 = ads.readADC_SingleEnded(0);
float voltageA0 = ads.computeVolts(rawA0);
Serial.printf("A0 raw=%d, voltage=%.4f V", rawA0, voltageA0);
if (READ_A1) {
int16_t rawA1 = ads.readADC_SingleEnded(1);
float voltageA1 = ads.computeVolts(rawA1);
Serial.printf(" | A1 raw=%d, voltage=%.4f V",
rawA1, voltageA1);
}
Serial.println();
delay(1000);
}ทำความเข้าใจคำสั่งสำคัญ
Wire.begin(21, 22)เริ่ม I2C ด้วย SDA = GPIO21 และ SCL = GPIO22ads.begin(0x48, &Wire)ตรวจการตอบรับของอุปกรณ์ในบัสก่อนเริ่มอ่านค่าads.setGain(GAIN_ONE)กำหนด FSR ±4.096V ไม่ใช่ระดับไฟเลี้ยงหรือแรงดันสูงสุดของขาอินพุตads.setDataRate(RATE_ADS1115_128SPS)ตั้งอัตราการแปลงภายใน ADC แต่โปรแกรมพิมพ์ค่าทุก 1 วินาทีเพราะมีdelay(1000)READ_A1 = falseไม่อ่านช่อง A1 ที่ยังไม่ได้ต่อสาย เพราะอินพุตที่ลอยอาจแสดงค่าที่ไม่มีความหมาย

นี่คือโค้ดสาธิตวงจร ไม่ใช่เฟิร์มแวร์ที่จัดการ I2C หลุด กลับมาเชื่อมต่อใหม่ ทำ Digital Filtering หรือบันทึก Calibration ลง Flash แล้ว
วิธีทดสอบ ADS1115 ให้รู้ว่าอ่านค่าได้จริง
- ก่อนเสียบ VR วัดด้วยมัลติมิเตอร์ว่า VDD ของ ADS1115 ได้ไฟประมาณ 3.3V และ GND ของทั้งสองบอร์ดเชื่อมถึงกัน
- ต่อ VR 10kΩ โดยปลายสองด้านต่อ 3V3 และ GND ส่วนขากลางต่อ A0 จากนั้นวัดแรงดันที่ขากลาง VR เทียบกับ GND
- ตรวจว่าที่ A0 ไม่มีแรงดันสูงกว่า 3.3V แล้วจึง Build/Upload โปรแกรม เปิด Serial Monitor 115200 baud
- หมุน VR ช้า ๆ ดูค่า
voltageเปลี่ยนตามแรงดันที่มิเตอร์อ่านได้โดยประมาณในช่วง 0–3.3V - ถ้าต้องการอ้างความแม่นยำ ให้บันทึกค่าเป็นตารางอย่างน้อยหลายจุด พร้อมชนิดมิเตอร์ สภาวะการวัด และค่าอ้างอิง ไม่ตัดสินจากเลขที่แสดงเพียงจุดเดียว



หมายเหตุ: ภาพถ่ายจากผู้ทดลองช่วยแสดงวิธีตรวจค่าเทียบกัน แต่ยังไม่ใช่ผลสอบเทียบความแม่นยำหรือผลการทดสอบซ้ำทุกจุด
ADS1115 ready. Turn VR at A0.
A0 raw=12000, voltage=1.5000 Vค่าตัวอย่าง 1.5000V มาจากการคำนวณสำหรับ GAIN_ONE เท่านั้น ยังไม่ได้ยืนยันด้วยฮาร์ดแวร์
อ่าน ADS1115 ไม่ได้ หรือค่าไม่นิ่ง ต้องตรวจอะไร?
| อาการ | จุดที่ควรตรวจ | แนวทางแก้ |
|---|---|---|
| ADS1115 not found | VDD, GND, SDA/SCL, ADDR | ตรวจสายและสแกน I2C หา 0x48–0x4B |
| ค่า A0 ไม่เปลี่ยน | ขากลาง VR ต่อถึง A0 ไหม | ใช้มิเตอร์วัด A0 เทียบกับ GND |
| ค่าค้างใกล้เพดาน | FSR ของ PGA เล็กกว่าสัญญาณ | วัดแรงดันจริงก่อนเลือกช่วง Gain ใหม่ |
| ค่ากระโดด | สายยาว, กราวด์, Noise, ภาคจ่ายไฟ | ลดสายให้สั้น ทดสอบ VR ก่อนเซนเซอร์ |
| A1 อ่านค่าแปลกทั้งที่ไม่ต่อ | ขา Analog ลอย | หยุดอ่าน A1 จนกว่าจะต่อสัญญาณถูกต้อง |
ตรวจ I2C Address ก่อนแก้สูตรวัด
ถ้าไม่พบอุปกรณ์ ควรสแกนบัสด้วยตัวอย่าง I2C Scanner ของ Arduino ก่อน สำหรับการต่อ ADDR ลง GND ในบทนี้คาดว่าจะพบ 0x48 การสุ่มเพิ่ม Offset หรือคูณค่า ADC โดยยังไม่ได้แก้การเดินสาย ไม่ช่วยให้ค่าที่วัดถูกต้องขึ้น
ต่อยอด ADS1115 ไปอ่านค่าเซนเซอร์ pH และ EC
ในงานเครื่องวัดคุณภาพน้ำ เราใช้โมดูล pH/EC ทำหน้าที่แปลงสัญญาณจากโพรบเป็นแรงดัน Analog แล้วให้ ADS1115 ส่งค่า Raw และ Voltage ไปยัง ESP32 ตัวอย่างการวางช่องคือ A0 สำหรับโมดูล pH และ A1 สำหรับโมดูล EC (ขึ้นอยู่กับการต่อจริง)
วัดแรงดันเอาต์พุตโมดูลทุกสภาวะที่คาดว่าจะใช้
อ่านแยกตามช่องและตรวจความนิ่ง
สอบเทียบตามสเปกโมดูล/น้ำยามาตรฐานจริง
ค่อยส่งค่าที่ตรวจแล้วไปยัง Dashboard
เอาต์พุต Analog อาจเกิน 3.3V ได้ ต้องวัดก่อนเสมอ และออกแบบการปรับระดับสัญญาณให้เหมาะกับภาคขยายและอิมพีแดนซ์ของเซนเซอร์ ไม่ควรต่อเข้า ADS1115 โดยตรงแบบเดาสุ่ม
ดูแนวคิดและความคืบหน้าของโครงงานได้จาก สร้างเครื่องวัด pH EC อุณหภูมิน้ำด้วย ESP32 และจอสัมผัส โดยการอ่าน Raw ADC สำเร็จยังไม่ถือว่าเครื่องวัด pH/EC สอบเทียบผ่าน
คำถามที่พบบ่อย (FAQ)
ADS1115 ใช้ไฟ 5V กับ ESP32 ได้หรือไม่?
ตัวชิป ADS1115 รองรับ VDD 2.0–5.5V แต่ ESP32 ใช้ลอจิก 3.3V ตัวอย่างนี้จึงเลือกไฟ 3.3V ทั้งระบบ หากจะใช้ VDD 5V ต้องตรวจ Pull-up และระดับลอจิก I2C แยกต่างหาก
ADS1115 อ่านสัญญาณ 4 ช่องพร้อมกันได้ไหม?
มีช่อง A0–A3 แบบ Single-ended สี่ช่อง แต่ชิปใช้ MUX เลือกแปลงทีละช่อง จึงต้องวนอ่านแต่ละช่อง ไม่ได้เก็บข้อมูลทั้งหมดในเวลาเดียวกัน
ADS1115 แปลงแรงดันเป็นค่า pH หรือ EC อัตโนมัติไหม?
ไม่ ADS1115 ทำหน้าที่แปลงแรงดันเป็นดิจิทัล การแปลงเป็น pH หรือ EC ต้องพึ่งข้อมูลโมดูล สูตร และการสอบเทียบด้วยมาตรฐานที่ถูกต้อง
ทำไม Raw ไม่ขึ้นถึง 32767 เมื่อไฟเลี้ยง 3.3V?
เพราะ Full-scale ของ PGA กับแรงดัน VDD เป็นคนละข้อจำกัด เมื่อใช้ GAIN_ONE สเกลด้านบวกไปถึง 4.096V แต่แรงดันที่ป้อนจริงต้องไม่เกิน VDD 3.3V จึงใช้ช่วง Count ด้านบวกไม่เต็ม
สรุป: อ่านแรงดันให้ถูก ก่อนนำไปแปลงค่าของเซนเซอร์
ถ้าต้องการใช้ ADS1115 กับ ESP32 ผมแนะนำให้เริ่มจาก VR 10kΩ และมัลติมิเตอร์ก่อน เพื่อแยกปัญหาสายไฟ I2C ค่า Gain และการอ่านแรงดันออกจากปัญหาการ Calibration ของเซนเซอร์ เมื่อวงจรทดสอบทำงานตามที่คาดไว้ จึงค่อยต่อสัญญาณจริงทีละช่อง และบันทึกผลอย่างเป็นระบบ




