ต่อ ADS1115 กับ ESP32 อย่างไร? อ่านค่า Analog ผ่าน I2C พร้อมโค้ด PlatformIO

สรุปก่อนต่อวงจร

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 ช่องพร้อมกัน

16-bit

ค่าดิจิทัลแบบ signed

A0–A3

อินพุต Single-ended 4 ช่อง

I2C

ใช้สาย SDA/SCL สองเส้น

8–860 SPS

อัตราแปลงสัญญาณตามที่เลือก

อย่าเพิ่งสรุปว่า ADC 16 บิตเท่ากับความแม่นยำของเครื่องวัด 16 บิต เพราะคุณภาพแหล่งจ่าย Noise วงจรขยายสัญญาณ การเดินสาย และ Calibration ยังส่งผลต่อค่าที่อ่านได้ อ่านสเปก ADS1115 จาก TI

ADS1115 ต่างจาก ADC ภายใน ESP32 อย่างไร?

ประเด็นADC ของ ESP32 รุ่นดั้งเดิมADS1115 ภายนอก
ความละเอียดทั่วไป12 บิต16 บิต signed
วิธีอ่านขา ADC ภายในผ่านบัส I2C
ช่องอินพุตขึ้นกับรุ่น/กลุ่ม ADC1 ADC24 ช่อง 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 เว็บไซต์อาจได้รับค่าคอมมิชชันเมื่อซื้อผ่านลิงก์

เตรียม ESP32 DevKit V1, ADS1115 Breakout, VR 10kΩ, Breadboard, Jumper, สาย USB และมัลติมิเตอร์สำหรับวัดแรงดัน โดยตรวจชื่อขาจากบอร์ดจริงก่อนเสียบสาย เพราะตำแหน่งขาแต่ละผู้ผลิตอาจไม่เรียงเหมือนกัน

ภาพถ่ายจริง ESP32 DevKit V1 และโมดูล ADS1115 บน Breadboard พร้อมสายต่อ I2C
ภาพถ่ายจากอุปกรณ์จริงบนโต๊ะทดลอง DevaDIY — ตำแหน่งขาของบอร์ดแต่ละรุ่นอาจต่างกัน ให้ใช้ตารางต่อสายด้านล่างเป็นหลัก
ESP32 / อุปกรณ์ADS1115หน้าที่
3V3VDDไฟเลี้ยง 3.3V
GNDGNDกราวด์ร่วม
GPIO21SDAI2C Data
GPIO22SCLI2C Clock
GNDADDRตั้ง Address 0x48
ขากลาง VR 10kΩA0 / AIN0แรงดันทดสอบ
ปลาย VR ด้านหนึ่งไป 3V3 อีกด้านไป GND—ปรับช่วงใกล้ 0–3.3V
ผังการเชื่อมต่อ ESP32 GPIO21 SDA และ GPIO22 SCL กับ ADS1115 ไฟ 3.3V พร้อมโพเทนชิออมิเตอร์ทดสอบช่อง A0
แผนภาพเชิงสัญญาณ ใช้ตรวจหน้าที่สาย ไม่ใช่ภาพประกอบฮาร์ดแวร์ที่ทดสอบผ่านแล้ว
ตรวจ Pull-up I2C

โมดูล 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 GainFull-scale Rangeแรงดันต่อ 1 Count (ประมาณ)
GAIN_TWOTHIRDS±6.144V187.5 µV
GAIN_ONE±4.096V125 µV
GAIN_TWO±2.048V62.5 µV
GAIN_FOUR±1.024V31.25 µV
สำคัญ: GAIN_ONE ไม่ได้แปลว่ารับไฟ 4.096V ได้

เมื่อชิปใช้ไฟเลี้ยง 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

  1. เปิด VS Code และ PlatformIO แล้วสร้างโปรเจกต์ใหม่ เลือกบอร์ด Espressif ESP32 Dev Module และ Framework เป็น Arduino
  2. กำหนดไฟล์ platformio.ini เพื่อเรียกใช้ไลบรารี Adafruit ADS1X15
  3. เขียนโค้ดลง src/main.cpp โดยอ่าน A0 ช่องเดียวก่อน
  4. เมื่อเช็กวงจรและไฟเลี้ยงแล้วจึง Build, Upload และเปิด Serial Monitor ที่ 115200 baud
ภาพถ่ายหน้าจอ VS Code PlatformIO แสดงโค้ดอ่าน ADS1115 และ Serial Monitor
ภาพจาก VS Code และ PlatformIO ที่เจ้าของเว็บถ่ายระหว่างทดสอบ ไม่ใช่หลักฐานยืนยันว่าโค้ดตัวอย่างในบทความผ่าน Build

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 = GPIO22
  • ads.begin(0x48, &Wire) ตรวจการตอบรับของอุปกรณ์ในบัสก่อนเริ่มอ่านค่า
  • ads.setGain(GAIN_ONE) กำหนด FSR ±4.096V ไม่ใช่ระดับไฟเลี้ยงหรือแรงดันสูงสุดของขาอินพุต
  • ads.setDataRate(RATE_ADS1115_128SPS) ตั้งอัตราการแปลงภายใน ADC แต่โปรแกรมพิมพ์ค่าทุก 1 วินาทีเพราะมี delay(1000)
  • READ_A1 = false ไม่อ่านช่อง A1 ที่ยังไม่ได้ต่อสาย เพราะอินพุตที่ลอยอาจแสดงค่าที่ไม่มีความหมาย
ภาพถ่าย Serial Monitor ขณะ ESP32 อ่านค่า Raw ADC และแรงดันจาก ADS1115
ภาพถ่าย Serial Monitor จากการทดลองจริง แสดงรูปแบบข้อมูล Raw และ Voltage ที่นำไปตรวจสอบได้

นี่คือโค้ดสาธิตวงจร ไม่ใช่เฟิร์มแวร์ที่จัดการ I2C หลุด กลับมาเชื่อมต่อใหม่ ทำ Digital Filtering หรือบันทึก Calibration ลง Flash แล้ว

วิธีทดสอบ ADS1115 ให้รู้ว่าอ่านค่าได้จริง

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

หมายเหตุ: ภาพถ่ายจากผู้ทดลองช่วยแสดงวิธีตรวจค่าเทียบกัน แต่ยังไม่ใช่ผลสอบเทียบความแม่นยำหรือผลการทดสอบซ้ำทุกจุด

ตัวอย่างรูปแบบ Serial Monitor ที่คาดว่าจะเห็น (ไม่ใช่ผลการทดลองจริง)
ADS1115 ready. Turn VR at A0.
A0 raw=12000, voltage=1.5000 V

ค่าตัวอย่าง 1.5000V มาจากการคำนวณสำหรับ GAIN_ONE เท่านั้น ยังไม่ได้ยืนยันด้วยฮาร์ดแวร์

อ่าน ADS1115 ไม่ได้ หรือค่าไม่นิ่ง ต้องตรวจอะไร?

อาการจุดที่ควรตรวจแนวทางแก้
ADS1115 not foundVDD, 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 (ขึ้นอยู่กับการต่อจริง)

1. ตรวจแรงดัน

วัดแรงดันเอาต์พุตโมดูลทุกสภาวะที่คาดว่าจะใช้

2. อ่าน Raw

อ่านแยกตามช่องและตรวจความนิ่ง

3. Calibration

สอบเทียบตามสเปกโมดูล/น้ำยามาตรฐานจริง

4. แสดงผล

ค่อยส่งค่าที่ตรวจแล้วไปยัง Dashboard

ระวังโมดูลเซนเซอร์ที่เลี้ยง 5V

เอาต์พุต 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 ของเซนเซอร์ เมื่อวงจรทดสอบทำงานตามที่คาดไว้ จึงค่อยต่อสัญญาณจริงทีละช่อง และบันทึกผลอย่างเป็นระบบ

เอกสารอ้างอิง

Shopping Cart
Scroll to Top