รายวิชา: 2302311 Integrated Chemistry Laboratory I ภาควิชา: เคมี คณะวิทยาศาสตร์ จุฬาลงกรณ์มหาวิทยาลัย Department of Chemistry, Faculty of Science, Chulalongkorn University
ระยะเวลา (Duration): 3 ชั่วโมง / 3 hours
TitraLab คือบอร์ดพัฒนาสำหรับการศึกษาที่ใช้ ESP32 สำหรับการไทเทรตกรด-เบสอัตโนมัติ บอร์ดนี้รวมเซ็นเซอร์ (pH probe, DS18B20), จอแสดงผล TFT 2.4", SD card, buzzer, LED และปั๊มเพอริสตาลติก (peristaltic pump) เข้าด้วยกัน
TitraLab is an ESP32-based educational development board for automated acid-base titration. It integrates sensors (pH probe, DS18B20 temperature), 2.4" TFT display, SD card, buzzer, LEDs, and a peristaltic pump.
┌─────────────────────────────────────────────────────────────────────┐
│ ระบบไทเทรตอัตโนมัติ │
│ Automated Titration System │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ [สารตัวอย่าง] ←── [ปั๊ม] ←── [สารไทแทรนต์] │
│ [Analyte] ←── [Pump] ←── [Titrant] │
│ │ │
│ ▼ │
│ [เซ็นเซอร์ pH] ──► [ESP32] ──► [จอ TFT + SD Card] │
│ [pH Sensor] ──► [ESP32] ──► [TFT + SD Card] │
│ │ │ │
│ │ ▼ │
│ │ [ตรวจจับจุดสมมูล] │
│ │ [Detect Equivalence Point] │
│ │ │ │
│ └──────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ TitraLab Learning Path │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ Week 1 Week 2 Week 3 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ พื้นฐาน │ ──► │ การสอบเทียบ │ ──► │ ระบบเต็ม │ │
│ │ Hardware │ │ Calibration │ │ Full System │ │
│ ├─────────────┤ ├─────────────┤ ├─────────────┤ │
│ │ LED/Button │ │ pH Sensor │ │ Titration │ │
│ │ ADC/PWM │ │ Pump Flow │ │ Loop │ │
│ │ Display │ │ OOP ขั้นกลาง │ │ Data Log │ │
│ │ OOP พื้นฐาน │ │ Inheritance │ │ MicroPad │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ความซับซ้อน: ง่าย ─────────────────────────────────────► ยาก │
│ Complexity: Simple ──────────────────────────────────► Complex │
│ │
└─────────────────────────────────────────────────────────────────────┘
หลังจากเรียนจบบทเรียนนี้ นิสิตจะสามารถ:
-
เข้าใจส่วนประกอบของบอร์ด TitraLab
- รู้จักอุปกรณ์ทุกชิ้นบนบอร์ด: LED, Button, เซ็นเซอร์ pH, เซ็นเซอร์อุณหภูมิ, ปั๊ม, จอ TFT
- เข้าใจบทบาทของแต่ละอุปกรณ์ในการไทเทรตอัตโนมัติ
-
เข้าใจพื้นฐานอิเล็กทรอนิกส์สำหรับการไทเทรต
- ADC (Analog-to-Digital Converter): แปลงสัญญาณจากเซ็นเซอร์ pH เป็นค่าดิจิทัล
- PWM (Pulse Width Modulation): ควบคุมความเร็วปั๊มสำหรับหยดสารไทแทรนต์
- สูตรการแปลงค่า: ADC → แรงดัน → pH
-
ใช้งานอุปกรณ์พื้นฐานได้
- ควบคุม LED แสดงสถานะ (เขียว = กำลังทำงาน, แดง = ถึงจุดสมมูล)
- อ่านปุ่มกดสำหรับควบคุมการไทเทรต
- อ่านค่าอุณหภูมิสำหรับชดเชยสมการ Nernst
- แสดงข้อมูลบนจอ TFT
-
เข้าใจ Class และ Object
- Class = พิมพ์เขียว (เหมือนแบบแปลนบีกเกอร์)
- Object = สิ่งที่สร้างจากพิมพ์เขียว (บีกเกอร์จริงแต่ละใบ)
-
เขียน Class อย่างง่ายได้
__init__= Constructor (ตัวสร้าง)- method = ฟังก์ชันในคลาส
self= ตัวอ้างอิงถึง object ปัจจุบัน
-
[เสริม] เข้าใจ DAC
- Digital-to-Analog Converter (ตรงข้ามกับ ADC)
ง่าย → ยาก (Simple → Complex)
Digital (0/1) → Analog (0-4095)
ผลลัพธ์ทันที (LED สว่าง) → ค่าที่ต้องคำนวณ (ADC)
| ช่วงเวลา | หัวข้อ | ไฟล์ | เวลา |
|---|---|---|---|
| ชั่วโมงที่ 1 | Digital I/O พื้นฐาน | 60 นาที | |
| 0:00-0:15 | แนะนำ TitraLab: ส่วนประกอบและเป้าหมาย | - | 15 นาที |
| 0:15-0:35 | LED (Digital Output): เปิด/ปิด | core/01_led_class.py |
20 นาที |
| → เคมี: แสดงสถานะ (เขียว = กำลังทำงาน, แดง = ถึงจุดสมมูล) | |||
| 0:35-0:50 | Button (Digital Input): กด/ไม่กด | core/02_button_class.py |
15 นาที |
| → เคมี: ควบคุมการไทเทรต (เริ่ม/หยุด/ยืนยัน) | |||
| 0:50-1:00 | พัก (Break) | - | 10 นาที |
| ชั่วโมงที่ 2 | Analog I/O สำหรับเซ็นเซอร์/ปั๊ม | 60 นาที | |
| 1:00-1:20 | ADC (Analog Input): อ่านค่า 0-4095 | core/03_adc_ph_basics.py |
20 นาที |
| → เคมี: เซ็นเซอร์ pH อ่านแรงดัน แปลงเป็น pH ด้วยสมการ Nernst | |||
| 1:20-1:35 | PWM (Analog-like Output): Duty cycle | core/04_pwm_pump_basics.py |
15 นาที |
| → เคมี: ควบคุมความเร็วปั๊ม (เร็วตอนเริ่ม, ช้าใกล้จุดสมมูล) | |||
| 1:35-1:50 | ADC+PWM รวมกัน: Pot -> LED Dimming | core/05_pot_led_dimming.py |
15 นาที |
| → เตรียมพร้อม: pH Sensor (ADC) -> Pump Speed (PWM) | |||
| 1:50-1:55 | เซ็นเซอร์อุณหภูมิ: ชดเชย Nernst | core/06_temp_sensor_class.py |
5 นาที |
| → เคมี: ความชัน Nernst เปลี่ยนตามอุณหภูมิ (59.16 mV ที่ 25°C) | |||
| 1:55-2:00 | พัก (Break) | - | 5 นาที |
| ชั่วโมงที่ 3 | จอแสดงผล, OOP และการรวมระบบ | 60 นาที | |
| 2:00-2:20 | จอ TFT: แสดง pH และกราฟ | core/07_display_basics.py |
20 นาที |
| 2:20-2:40 | OOP พื้นฐาน: Class และ Object | core/08_intro_oop.py |
20 นาที |
| → เปรียบเทียบ: Class = พิมพ์เขียวบีกเกอร์, Object = บีกเกอร์จริงแต่ละใบ | |||
| 2:40-2:55 | ตัวอย่างรวม: Lab Alert System | core/09_combined_example.py |
15 นาที |
| 2:55-3:00 | สรุปและเชื่อมโยงกับ Week 2 (การสอบเทียบ) | - | 5 นาที |
| ลำดับ | หัวข้อ | ความซับซ้อน | เหตุผล |
|---|---|---|---|
| 1 | LED | ง่ายมาก | 1 bit (0/1), เห็นผลทันที (ไฟติด/ดับ) |
| 2 | Button | ง่าย | 1 bit (กด/ไม่กด), เข้าใจ input |
| 3 | ADC | ซับซ้อน | 12 bit (0-4095), ต้องแปลงค่า |
| 4 | PWM | ซับซ้อน | 10 bit (0-1023), ต้องเข้าใจ duty cycle |
หมายเหตุ: สอน Digital ก่อน Analog เหมือนสอนนับเลขก่อนสอนแคลคูลัส
Week_1/
├── core/ # [หลัก] ไฟล์สำหรับสอนในห้องเรียน (เรียงตามลำดับการสอน)
│ ├── 01_led_class.py # ชม.1: คลาส LED - แสดงสถานะการไทเทรต
│ ├── 02_button_class.py # ชม.1: คลาส Button - ควบคุมการไทเทรต
│ ├── 03_adc_ph_basics.py # ชม.2: พื้นฐาน ADC สำหรับเซ็นเซอร์ pH
│ ├── 04_pwm_pump_basics.py # ชม.2: พื้นฐาน PWM สำหรับควบคุมปั๊ม
│ ├── 05_pot_led_dimming.py # ชม.2: Pot (ADC) -> LED (PWM) รวมกัน
│ ├── 06_temp_sensor_class.py # ชม.2: คลาส TemperatureSensor - สมการ Nernst
│ ├── 07_display_basics.py # ชม.3: พื้นฐานจอ TFT Display
│ ├── 08_intro_oop.py # ชม.3: บทนำ OOP (ตัวอย่างคลาส Beaker)
│ ├── 09_combined_example.py # ชม.3: ตัวอย่างรวม Lab Alert System
│ ├── ex_status_led.py # แบบฝึกหัด: คลาส StatusLED
│ └── README.md # คู่มือโฟลเดอร์ core
│
├── extras/ # [เสริม] สื่อเพิ่มเติม
│ ├── 01_procedural/ # ตัวอย่างแบบ Procedural (ไม่ใช้ OOP)
│ │ ├── 01_basic.py # LED พื้นฐาน
│ │ ├── 02_toggle.py # สลับ LED
│ │ ├── 02_basic_loop.py # LED กระพริบใน loop
│ │ ├── 03_twoLed.py # ควบคุม LED 2 ดวง
│ │ ├── 03_Potentiometer.py # อ่านค่า ADC
│ │ ├── 04_twoLed_infiniteLoop.py # LED 2 ดวงใน infinite loop
│ │ └── 04_PWM_OUT.py # PWM ควบคุม LED
│ ├── 02_advanced_oop/ # OOP ขั้นสูง
│ ├── 03_exercises/ # แบบฝึกหัดพร้อมเฉลย
│ ├── 04_hardware/ # ตัวอย่างเฉพาะฮาร์ดแวร์
│ │ ├── Buzzer/ # Buzzer - แจ้งเตือนจุดสมมูล
│ │ ├── DAC/ # DAC (Digital-to-Analog)
│ │ ├── DS18B20/ # เซ็นเซอร์อุณหภูมิ
│ │ ├── SDCard/ # SD Card - บันทึกข้อมูล
│ │ └── TFT/ # จอ TFT - แสดง pH และกราฟ
│ ├── 05_reference/ # เอกสารอ้างอิง
│ └── archive/ # [เก็บถาวร] ตัวอย่าง ADC/PWM แบบละเอียด
│ ├── 07_ADC/ # ตัวอย่าง ADC หลายไฟล์
│ └── 07_PWM/ # ตัวอย่าง PWM หลายไฟล์
│
├── lib/ # ไลบรารีที่จำเป็น (อัปโหลดไปยัง ESP32)
│ ├── ili9341.py # ไดรเวอร์จอ TFT
│ ├── xglcd_font.py # ไลบรารีแสดงฟอนต์
│ ├── sdcard.py # ไลบรารี SD Card
│ └── titralab_simple.py # คลาสพื้นฐาน TitraLab (LED, Button, etc.)
│
├── fonts/ # ไฟล์ฟอนต์ (อัปโหลดไปยัง ESP32)
│ ├── ArcadePix9x11.c # ฟอนต์เล็ก
│ └── EspressoDolce18x24.c # ฟอนต์ใหญ่
│
├── pins.py # การกำหนดขา GPIO มาตรฐาน
└── README.md # ไฟล์นี้
| ชั่วโมง | หัวข้อ | ไฟล์หลัก | ไฟล์เสริม |
|---|---|---|---|
| 1 | LED | core/01_led_class.py |
extras/01_procedural/01_basic.py |
| 1 | Button | core/02_button_class.py |
extras/01_procedural/02_toggle.py |
| 2 | ADC | core/03_adc_ph_basics.py |
extras/01_procedural/03_Potentiometer.py |
| 2 | PWM | core/04_pwm_pump_basics.py |
extras/01_procedural/04_PWM_OUT.py |
| 2 | ADC+PWM | core/05_pot_led_dimming.py |
- |
| 2 | Temperature | core/06_temp_sensor_class.py |
extras/04_hardware/DS18B20/ |
| 3 | TFT Display | core/07_display_basics.py |
extras/04_hardware/TFT/ |
| 3 | OOP | core/08_intro_oop.py |
- |
| 3 | Combined | core/09_combined_example.py |
- |
Thonny เป็น IDE (Integrated Development Environment/สภาพแวดล้อมพัฒนาโปรแกรม) ที่เหมาะสำหรับนิสิตที่เริ่มต้นเรียนรู้การเขียนโปรแกรม รองรับ MicroPython บน ESP32 โดยมีหน้าต่างแสดงผลที่เข้าใจง่าย
- เปิดเว็บไซต์ https://thonny.org
- คลิกปุ่มดาวน์โหลดตามระบบปฏิบัติการ:
- Windows: คลิก "Windows" แล้วรันไฟล์
.exe - macOS: คลิก "Mac" แล้วลากไปใส่ Applications
- Linux: ใช้คำสั่ง
pip install thonnyหรือดาวน์โหลดจากเว็บ
- Windows: คลิก "Windows" แล้วรันไฟล์
- ติดตั้งตามขั้นตอนปกติ (Next > Next > Install)
- เปิด Thonny
- ไปที่ Tools > Options (เครื่องมือ > ตัวเลือก)
- เลือกแท็บ Interpreter (ตัวแปลภาษา)
- เลือก "MicroPython (ESP32)" จากรายการแบบเลื่อนลง
- เลือก Port (พอร์ต):
- Windows: เลือก COM port เช่น
COM3,COM4(ดูใน Device Manager) - macOS/Linux: เลือก
/dev/ttyUSB0หรือ/dev/cu.usbserial-xxxx
- Windows: เลือก COM port เช่น
- คลิก OK
เคล็ดลับ (Tip): หากไม่เห็น COM port ให้ตรวจสอบว่าติดตั้ง CP210x USB driver แล้ว (TitraLab ใช้ CP210x bridge controller - ดาวน์โหลดได้ที่ https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers)
- ดูที่ Shell panel ด้านล่าง
- ถ้าเชื่อมต่อสำเร็จจะเห็น:
MicroPython v1.xx.x on xxxx-xx-xx; ESP32 module with ESP32 Type "help()" for more information. >>> - พิมพ์
print("Hello")แล้วกด Enter เพื่อทดสอบ
ก่อนรันโค้ดที่ใช้ TFT Display หรือไลบรารีอื่น นิสิตต้องอัปโหลดไฟล์ที่จำเป็นไปยัง ESP32 ก่อน
- ไปที่ View > Files (มุมมอง > ไฟล์)
- จะเห็นหน้าต่างแบ่งเป็น 2 ส่วน:
- ซ้ายบน: ไฟล์ในคอมพิวเตอร์ (This computer)
- ซ้ายล่าง: ไฟล์ใน ESP32 (MicroPython device)
- ในส่วน "This computer" นำทางไปยังไฟล์ที่ต้องการ
- คลิกขวา ที่ไฟล์ (เช่น
ili9341.py) - เลือก "Upload to /" (อัปโหลดไปยัง /)
- ไฟล์จะปรากฏในส่วน "MicroPython device"
- ในส่วน "This computer" นำทางไปยังโฟลเดอร์ที่ต้องการ
- คลิกขวา ที่โฟลเดอร์ (เช่น
lib/หรือfonts/) - เลือก "Upload to /"
- โฟลเดอร์และไฟล์ทั้งหมดจะถูกอัปโหลด
| วิธี | ใช้เมื่อ |
|---|---|
| Upload to / | อัปโหลดไฟล์/โฟลเดอร์ที่มีอยู่แล้วในคอมพิวเตอร์ |
| File > Save as | บันทึกไฟล์ที่เปิดอยู่ใน Thonny ไปยัง ESP32 (เลือก "MicroPython device" ในกล่อง Save) |
- เปิดไฟล์
.pyจากคอมพิวเตอร์ (File > Open หรือดับเบิลคลิกใน File Browser) - คลิกปุ่ม Run (สีเขียว) หรือกด F5
- โค้ดจะถูกส่งไปรันบน ESP32
- ดูผลลัพธ์ใน Shell panel ด้านล่าง
- ในส่วน "MicroPython device" ดับเบิลคลิกไฟล์
.py - คลิกปุ่ม Run (F5)
- กดปุ่ม Stop (สีแดง) หรือกด Ctrl+C
- หากโค้ดค้าง ให้กดปุ่ม Reset บน ESP32 (ปุ่ม EN หรือ RST)
- ผลลัพธ์แสดงใน Shell panel ด้านล่าง
- ข้อความ
print()จะปรากฏที่นี่ - ข้อผิดพลาด (Error/ข้อผิดพลาด) จะแสดงเป็นสีแดง
อาการ: ไม่สามารถเชื่อมต่อ ESP32 ได้
วิธีแก้:
- ตรวจสอบสาย USB - ลองใช้สายอื่น (บางสายชาร์จอย่างเดียว ไม่ส่งข้อมูล)
- ตรวจสอบ COM port ใน Tools > Options > Interpreter
- ลองถอดและเสียบสาย USB ใหม่
- ตรวจสอบว่าติดตั้ง CP210x USB driver แล้ว (TitraLab ใช้ CP210x bridge controller)
- ปิดโปรแกรมอื่นที่อาจใช้ COM port อยู่ (เช่น Arduino IDE, Serial Monitor)
อาการ: ImportError: no module named 'ili9341'
วิธีแก้:
- อัปโหลดไฟล์ไลบรารี (library/ไลบรารี) ที่จำเป็นไปยัง ESP32 ก่อน
- สำหรับ Week 1 ต้องอัปโหลด:
- โฟลเดอร์
lib/(มีili9341.py,xglcd_font.py,sdcard.py) - โฟลเดอร์
fonts/(มีไฟล์.c)
- โฟลเดอร์
- ตรวจสอบว่าไฟล์อยู่ใน root directory ของ ESP32 (
/lib/,/fonts/)
อาการ: พิมพ์คำสั่งใน Shell แล้วไม่มีอะไรเกิดขึ้น
วิธีแก้:
- กด Ctrl+C เพื่อหยุดโปรแกรมที่กำลังทำงาน
- คลิกปุ่ม Stop/Restart (สีแดง)
- กดปุ่ม Reset บน ESP32 (ปุ่ม EN หรือ RST)
- ถอดและเสียบสาย USB ใหม่
- ใน Thonny: Run > Interrupt execution แล้ว Device > Soft reboot
อาการ: OSError: [Errno 2] ENOENT เมื่อโหลดฟอนต์
วิธีแก้:
- อัปโหลดโฟลเดอร์
fonts/ไปยัง ESP32 - ตรวจสอบว่าโครงสร้างเป็น
/fonts/ArcadePix9x11.cไม่ใช่/ArcadePix9x11.c - ตรวจสอบชื่อไฟล์ให้ตรงกับที่ใช้ในโค้ด (ตัวพิมพ์เล็ก-ใหญ่ต้องตรงกัน/case-sensitive)
อาการ: MemoryError หรือ memory allocation failed
วิธีแก้:
- กด Reset บน ESP32 เพื่อล้างหน่วยความจำ
- หลีกเลี่ยงการรันโค้ดซ้ำหลายครั้งโดยไม่ Reset
- ลบไฟล์ที่ไม่จำเป็นออกจาก ESP32
ทำตามขั้นตอนนี้เพื่อรันโค้ดแรกบนบอร์ด TitraLab สำเร็จ:
- ใช้สาย USB เชื่อมต่อบอร์ด TitraLab (ESP32) กับคอมพิวเตอร์
- รอให้ Windows/macOS รู้จักอุปกรณ์ (อาจมีเสียง)
- เปิด Thonny IDE
- ไปที่ Tools > Options > Interpreter
- เลือก "MicroPython (ESP32)"
- เลือก COM port ที่ถูกต้อง
- คลิก OK
- ตรวจสอบว่าเห็น
>>>ใน Shell
- ไปที่ View > Files เพื่อเปิด File Browser
- นำทางไปยังโฟลเดอร์
Week_1/lib/ - คลิกขวาที่โฟลเดอร์
lib - เลือก "Upload to /"
- รอจนอัปโหลดเสร็จ (ดูสถานะใน Shell)
- นำทางไปยังโฟลเดอร์
Week_1/fonts/ - คลิกขวาที่โฟลเดอร์
fonts - เลือก "Upload to /"
- รอจนอัปโหลดเสร็จ
- ไปที่ File > Open (Ctrl+O)
- นำทางไปยัง
Week_1/core/01_led_class.py - เปิดไฟล์
- คลิกปุ่ม Run (สีเขียว) หรือกด F5
- ดูผลลัพธ์ใน Shell panel:
================================================== ทดสอบคลาส LED - จำลองสถานะระบบไทเทรชัน LED Class Test - Simulate Titration System Status ================================================== LED 'Red-Error' พร้อมใช้งานที่ GPIO2 (ready) LED 'Green-Status' พร้อมใช้งานที่ GPIO4 (ready) ...
- ลองเปลี่ยนจำนวนครั้งกระพริบ เช่น:
led_green.blink(5, 0.2) # กระพริบ 5 ครั้ง
- กด F5 เพื่อรันใหม่
- สังเกตผลลัพธ์ที่เปลี่ยนไป
ตารางต่อไปนี้แสดงการกำหนดขา GPIO มาตรฐานของบอร์ด TitraLab (ดูรายละเอียดเพิ่มเติมในไฟล์ pins.py)
| อุปกรณ์ (Component) | GPIO | หมายเหตุ (Notes) |
|---|---|---|
| LED แสดงสถานะ (Status LEDs) | ||
| LED สีแดง (Red) | 2 | Output - แสดงสถานะ เช่น ถึงจุดสมมูล |
| LED สีเขียว (Green) | 4 | Output - แสดงสถานะ เช่น กำลังไทเทรต |
| ปุ่มกด (Buttons) | ||
| Button 1 | 34 | Input-only, ใช้ external pull-down |
| Button 2 | 35 | Input-only, ใช้ external pull-down |
| Button 3 | 39 | Input-only, ใช้ external pull-down |
| เซ็นเซอร์ (Sensors) | ||
| DS18B20 เซ็นเซอร์อุณหภูมิ | 16 | OneWire protocol |
| pH Sensor (ADC) | 32 | อ่านค่าแรงดันจากหัววัด pH (ADC1 — ใช้ขาร่วมกับ POT1, ห้ามใช้ GPIO25) |
| Potentiometer (ตัวต้านทานปรับค่า) | ||
| POT1 | 32 | ADC input |
| POT2 | 33 | ADC input |
| Actuator (อุปกรณ์ขับเคลื่อน) | ||
| Buzzer | 26 | PWM output |
| Pump (ปั๊ม) | 21 | PWM output - ควบคุมปั๊มไทเทรชัน |
| TFT Display (SPI Bus 1) | ||
| TFT SCK | 14 | SPI Clock |
| TFT MOSI | 13 | SPI Data |
| TFT DC | 27 | Data/Command |
| TFT CS | 15 | Chip Select |
| TFT RST | 0 | Reset |
| SD Card (SoftSPI) | ||
| SD MISO | 19 | SPI Data In |
| SD MOSI | 23 | SPI Data Out |
| SD SCK | 18 | SPI Clock |
| SD CS | 5 | Chip Select |
หมายเหตุสำคัญ: GPIO 34, 35, 39 เป็นขา input-only ไม่สามารถใช้ internal pull-up/pull-down ได้ บอร์ด TitraLab ใช้ external pull-down resistor
ส่วนนี้อธิบายแนวคิดพื้นฐานของ ADC, PWM และ DAC ที่จำเป็นสำหรับการทำงานกับเซ็นเซอร์และอุปกรณ์ควบคุมในระบบ TitraLab การเข้าใจแนวคิดเหล่านี้จะช่วยให้นิสิตเตรียมพร้อมสำหรับสัปดาห์ที่ 2 ที่จะใช้งานเซ็นเซอร์ pH และควบคุมปั๊ม
This section explains the fundamentals of ADC, PWM, and DAC essential for working with sensors and actuators in the TitraLab system. Understanding these concepts prepares students for Week 2 where pH sensor and pump control are implemented.
ADC (Analog-to-Digital Converter / ตัวแปลงสัญญาณแอนะล็อกเป็นดิจิทัล) คืออุปกรณ์ที่แปลงสัญญาณแอนะล็อก (แรงดันไฟฟ้าต่อเนื่อง) เป็นสัญญาณดิจิทัล (ตัวเลข) ที่ไมโครคอนโทรลเลอร์สามารถประมวลผลได้
ADC (Analog-to-Digital Converter) converts continuous analog voltage signals into digital numbers that a microcontroller can process.
| คุณสมบัติ (Property) | ค่า (Value) | คำอธิบาย (Description) |
|---|---|---|
| ความละเอียด (Resolution) | 12-bit | ค่าที่อ่านได้อยู่ในช่วง 0-4095 |
| ช่วงแรงดัน (Voltage Range) | 0-3.3V | ที่ ATTN_11DB (attenuation 11dB) |
| ขา ADC1 | GPIO 32-39 | ใช้งานได้ตลอดเวลา |
| ขา ADC2 | GPIO 0,2,4,12-15,25-27 | ใช้ไม่ได้เมื่อ WiFi ทำงาน |
แรงดัน (V) = (ค่า ADC / 4095) x 3.3V
Voltage (V) = (ADC value / 4095) x 3.3V
ตัวอย่าง: ถ้าอ่านค่า ADC ได้ 2048 (ครึ่งหนึ่งของ 4095)
- แรงดัน = (2048 / 4095) x 3.3V = 1.65V (ครึ่งหนึ่งของ 3.3V)
เซ็นเซอร์ pH ของ TitraLab เชื่อมต่อที่ GPIO32 (ADC1) และส่งออกแรงดันไฟฟ้าตามค่า pH ของสารละลาย โดยอิงตามสมการ Nernst:
The TitraLab pH sensor connects to GPIO32 (ADC1) and outputs voltage proportional to the solution's pH, based on the Nernst equation:
E = E0 - (2.303RT/nF) x pH
ที่อุณหภูมิ 25C: slope = -59.16 mV ต่อหน่วย pH
At 25C: slope = -59.16 mV per pH unit
| ค่า pH | แรงดันโดยประมาณ (mV) | คำอธิบาย |
|---|---|---|
| 4.00 | ~177 mV above neutral | กรด (Acidic) |
| 7.00 | ~0 mV (neutral point) | กลาง (Neutral) |
| 10.00 | ~-177 mV below neutral | เบส (Basic) |
from machine import Pin, ADC
# สร้าง ADC object ที่ GPIO32 (Potentiometer)
# Create ADC object on GPIO32 (Potentiometer)
adc = ADC(Pin(32))
# ตั้งค่า attenuation เป็น 11dB สำหรับอ่าน 0-3.3V
# Set attenuation to 11dB for 0-3.3V range
adc.atten(ADC.ATTN_11DB)
# อ่านค่าดิบ (0-4095) (Read raw value)
raw_value = adc.read()
# แปลงเป็นแรงดันไฟฟ้า (Convert to voltage)
voltage = (raw_value / 4095) * 3.3
print(f"ค่า ADC (ADC Value): {raw_value}")
print(f"แรงดัน (Voltage): {voltage:.3f} V")PWM (Pulse Width Modulation / การมอดูเลตความกว้างพัลส์) คือเทคนิคการสร้างสัญญาณดิจิทัลที่สลับระหว่าง HIGH และ LOW อย่างรวดเร็ว โดยควบคุม "ความกว้าง" ของพัลส์ HIGH เพื่อจำลองสัญญาณแอนะล็อก
PWM (Pulse Width Modulation) creates a digital signal that rapidly switches between HIGH and LOW, controlling the "width" of HIGH pulses to simulate analog output.
Duty Cycle คือสัดส่วนเวลาที่สัญญาณอยู่ที่ HIGH ต่อหนึ่งรอบ วัดเป็นเปอร์เซ็นต์:
Duty Cycle is the proportion of time the signal stays HIGH per cycle, measured as percentage:
สัญญาณ PWM (PWM Signal):
_____ _____ _____
25% Duty Cycle: ___| |_____| |_____| |_____
_________ _________ _________
50% Duty Cycle: ___| |_| |_| |_
_____________ ___________ _____
75% Duty Cycle: ___| |_| |_|
_______________________________________________
100% Duty Cycle: ___|
| คุณสมบัติ (Property) | ค่า (Value) | คำอธิบาย (Description) |
|---|---|---|
| ความละเอียด (Resolution) | 10-bit | ค่า duty อยู่ในช่วง 0-1023 |
| ช่วงความถี่ (Frequency Range) | 1 Hz - 40 MHz | ปรับได้ตามต้องการ |
| Duty 0% | duty = 0 | ปิดสนิท (OFF) |
| Duty 100% | duty = 1023 | เปิดเต็มที่ (Full ON) |
ค่า duty (0-1023) = (เปอร์เซ็นต์ / 100) x 1023
duty value (0-1023) = (percentage / 100) x 1023
ตัวอย่าง: ต้องการ 50% duty cycle
- ค่า duty = (50 / 100) x 1023 = 511 (หรือ 512)
ปั๊มไทเทรชันของ TitraLab เชื่อมต่อที่ GPIO21 และควบคุมด้วย PWM เพื่อปรับอัตราการไหลของสารไทแทรนต์ (titrant):
The TitraLab titration pump connects to GPIO21 and uses PWM to control the flow rate of titrant:
| Duty Cycle | ความเร็วปั๊ม (Pump Speed) | การใช้งาน (Application) |
|---|---|---|
| 0% | หยุด (Stopped) | ไม่หยดสาร |
| 25% | ช้า (Slow) | ใกล้จุดสมมูล (near equivalence point) |
| 50% | ปานกลาง (Medium) | ช่วงกลางการไทเทรต |
| 100% | เร็ว (Fast) | ช่วงเริ่มต้น (initial stage) |
สำคัญ: เมื่อใกล้ถึงจุดสมมูล (equivalence point) ต้องลด duty cycle เพื่อหยดสารช้าลง จะได้ค่า pH ที่แม่นยำ
from machine import Pin, PWM
import time
# สร้าง PWM object ที่ GPIO2 (LED สีแดง)
# Create PWM object on GPIO2 (Red LED)
led = PWM(Pin(2), freq=500)
# ค่อยๆ เพิ่มความสว่าง (Fade in)
for duty in range(0, 1024, 10):
led.duty(duty)
time.sleep(0.01)
# ค่อยๆ ลดความสว่าง (Fade out)
for duty in range(1023, -1, -10):
led.duty(duty)
time.sleep(0.01)
# สำคัญ: คืนทรัพยากร PWM เมื่อเลิกใช้
# Important: Release PWM resources when done
led.duty(0)
led.deinit()DAC (Digital-to-Analog Converter / ตัวแปลงสัญญาณดิจิทัลเป็นแอนะล็อก) คืออุปกรณ์ที่ทำงานตรงข้ามกับ ADC โดยแปลงค่าตัวเลขดิจิทัลเป็นแรงดันไฟฟ้าแอนะล็อก
DAC (Digital-to-Analog Converter) works opposite to ADC, converting digital numbers to analog voltage output.
| คุณสมบัติ (Property) | ค่า (Value) | คำอธิบาย (Description) |
|---|---|---|
| ความละเอียด (Resolution) | 8-bit | ค่าที่กำหนดได้อยู่ในช่วง 0-255 |
| ช่วงแรงดัน (Voltage Range) | 0-3.3V | แรงดันเอาต์พุต |
| ขา DAC | GPIO 25, GPIO 26 | ESP32 มี DAC 2 ช่อง |
| แนวคิด (Concept) | ทิศทาง (Direction) | ความละเอียด (Resolution) | การใช้งาน (Use Case) |
|---|---|---|---|
| ADC | Analog -> Digital | 12-bit (0-4095) | อ่านค่าเซ็นเซอร์ pH, Potentiometer |
| PWM | Digital -> "Analog" | 10-bit (0-1023) | ควบคุมความสว่าง LED, ความเร็วปั๊ม |
| DAC | Digital -> Analog | 8-bit (0-255) | สร้างแรงดันอ้างอิง, สัญญาณเสียง |
หมายเหตุ: PWM ไม่ใช่ analog จริง แต่สัญญาณที่สลับเร็วๆ ทำให้ "ดูเหมือน" analog เมื่อใช้กับอุปกรณ์บางชนิด (เช่น LED, มอเตอร์)
from machine import Pin, DAC
# สร้าง DAC object ที่ GPIO26
# Create DAC object on GPIO26
dac = DAC(Pin(26))
# กำหนดค่าแรงดันเอาต์พุต
# Set output voltage
# 0 = 0V, 128 = 1.65V, 255 = 3.3V
dac.write(128) # ประมาณ 1.65V
# สร้างสัญญาณคลื่นซายน์อย่างง่าย (Simple sine wave)
import math
import time
for i in range(360):
value = int(127.5 + 127.5 * math.sin(math.radians(i)))
dac.write(value)
time.sleep_ms(5)เชื่อมต่อกับสัปดาห์ที่ 2: การประยุกต์ใช้ ADC และ PWM (Connection to Week 2: ADC and PWM Applications)
ในสัปดาห์ที่ 2 นิสิตจะนำความรู้พื้นฐาน ADC และ PWM ไปประยุกต์ใช้กับการควบคุมระบบ TitraLab จริง:
In Week 2, students will apply ADC and PWM fundamentals to control the actual TitraLab system:
[สารละลาย] -> [เซ็นเซอร์ pH] -> [ADC GPIO32] -> [คำนวณ pH]
[Solution] -> [pH Sensor] -> [ADC GPIO32] -> [Calculate pH]
สมการแปลงค่า (Conversion Equation):
pH = slope x voltage + intercept
โดย slope และ intercept ได้จากการสอบเทียบ (calibration)
ด้วยสารละลายกันชนมาตรฐาน (standard buffer solutions)
คลาส PHSensor ในสัปดาห์ที่ 2:
read_voltage()- อ่านแรงดันจาก ADC และกรองสัญญาณรบกวนread_ph()- แปลงแรงดันเป็นค่า pH ด้วยสมการสอบเทียบcalibrate()- สอบเทียบเซ็นเซอร์ด้วยสารละลายกันชน pH 4.00 และ 7.00
[คำสั่งควบคุม] -> [PWM GPIO21] -> [ปั๊ม] -> [สารไทแทรนต์]
[Control Command] -> [PWM GPIO21] -> [Pump] -> [Titrant]
การคำนวณปริมาตร (Volume Calculation):
volume (mL) = flow_rate (mL/s) x time (s) x (duty_cycle / 100)
คลาส Pump ในสัปดาห์ที่ 2:
start(duty_percent)- เริ่มปั๊มที่ความเร็วที่กำหนดstop()- หยุดปั๊มและคืนค่าเวลา/ปริมาตรที่หยดrun_for_volume(mL)- หยดสารตามปริมาตรที่กำหนด
# ตัวอย่างแนวคิด (Conceptual example)
# โค้ดเต็มจะเรียนในสัปดาห์ที่ 2-3
while True:
# อ่านค่า pH ด้วย ADC
ph = ph_sensor.read_ph()
# ตรวจสอบจุดสมมูล
if detect_equivalence_point(ph):
pump.stop()
break
# ปรับความเร็วปั๊มตามค่า pH
if abs(ph - target_ph) < 0.5:
pump.set_duty(25) # ช้า - ใกล้จุดสมมูล
else:
pump.set_duty(100) # เร็ว - ห่างจากจุดสมมูลclass ClassName:
"""Class = พิมพ์เขียว (Blueprint) สำหรับสร้าง Object"""
def __init__(self, parameter):
"""
Constructor (ตัวสร้าง) - ทำงานอัตโนมัติเมื่อสร้าง object
ใช้กำหนดค่าเริ่มต้นให้กับ object
"""
self.attribute = parameter # Instance variable (ตัวแปรของ object)
def method_name(self):
"""Method (เมธอด) = ฟังก์ชันที่อยู่ใน class"""
return self.attributeself = ตัวอ้างอิงถึง object ปัจจุบัน (reference to current object)
self.pin_numberหมายถึงpin_numberของ object นี้โดยเฉพาะ- เมื่อมี LED 2 ดวง แต่ละดวงมี
self.pin_numberของตัวเอง (เหมือนบีกเกอร์ 2 ใบ แต่ละใบมีปริมาตรของตัวเอง)
# Class = พิมพ์เขียว, Object = สิ่งที่สร้างจากพิมพ์เขียว (Instance)
led_red = LED(2, "Red") # Object ที่ 1 - LED สีแดงที่ GPIO2
led_green = LED(4, "Green") # Object ที่ 2 - LED สีเขียวที่ GPIO4
led_red.on() # เรียก method ของ object led_red
led_green.off() # เรียก method ของ object led_greenโค้ดด้านล่างแสดงการสร้างคลาส LED สำหรับควบคุมไฟ LED ซึ่งใช้แสดงสถานะการไทเทรต เช่น สีเขียว = กำลังทำงาน, สีแดง = ถึงจุดสมมูล (equivalence point)
from machine import Pin
import time
class LED:
"""คลาสควบคุม LED (LED Control Class)"""
def __init__(self, pin_number, name="LED"):
"""สร้าง LED object (Create LED object)"""
self.pin_number = pin_number
self.name = name
self.is_on = False
# สร้าง Pin เป็น OUTPUT (Create Pin as OUTPUT)
self._pin = Pin(pin_number, Pin.OUT)
self._pin.value(0) # เริ่มต้นปิด (Start off)
def on(self):
"""เปิด LED (Turn LED on)"""
self._pin.value(1)
self.is_on = True
def off(self):
"""ปิด LED (Turn LED off)"""
self._pin.value(0)
self.is_on = False
def toggle(self):
"""สลับสถานะ (Toggle state)"""
if self.is_on:
self.off()
else:
self.on()
def blink(self, times=1, delay_sec=0.3):
"""กระพริบ LED (Blink LED)"""
for _ in range(times):
self._pin.value(1)
time.sleep(delay_sec)
self._pin.value(0)
time.sleep(delay_sec)คลาส Button ใช้อ่านสถานะปุ่มกดพร้อม debounce (การกำจัดสัญญาณรบกวนจากการกดปุ่ม) ปุ่มกดบนบอร์ด TitraLab ใช้สำหรับ:
- Button 1 (GPIO34): เริ่ม/หยุดการไทเทรต
- Button 2 (GPIO35): ยืนยันการสอบเทียบ (calibration)
- Button 3 (GPIO39): ยกเลิก/ออก
from machine import Pin
import time
class Button:
"""คลาสอ่านปุ่มกดพร้อม Debounce (Button class with debounce)"""
def __init__(self, pin_number, name="Button", debounce_ms=200):
"""สร้าง Button (Create Button object)"""
self.pin_number = pin_number
self.name = name
self.debounce_ms = debounce_ms
self._pin = Pin(pin_number, Pin.IN)
self._last_press_time = 0
self._was_pressed = False
def is_active(self):
"""ตรวจสอบว่ากดอยู่ (Check if currently pressed)"""
return self._pin.value() == 1
def is_pressed(self):
"""
ตรวจจับการกดใหม่พร้อม debounce
Returns True only ONCE per press (คืนค่า True แค่ครั้งเดียวต่อการกด)
"""
current_time = time.ticks_ms()
is_active_now = self.is_active()
if is_active_now and not self._was_pressed:
if time.ticks_diff(current_time, self._last_press_time) > self.debounce_ms:
self._last_press_time = current_time
self._was_pressed = True
return True
if not is_active_now:
self._was_pressed = False
return Falseคลาส TemperatureSensor ไม่เพียงแค่อ่านค่าอุณหภูมิ แต่ยังสามารถแปลงหน่วยเป็น Kelvin และคำนวณค่าที่ใช้ในสมการ Nernst ได้ ซึ่งเป็นสมการสำคัญในการคำนวณค่า pH จากแรงดันไฟฟ้า:
สมการ Nernst: E = E0 - (2.303RT/nF) x pH
ที่อุณหภูมิ 25 C ค่า 2.303RT/nF = 59.16 mV ต่อหน่วย pH
class TemperatureSensor:
"""เซ็นเซอร์อุณหภูมิพร้อมการคำนวณทางเคมี"""
R_JOULES = 8.314 # ค่าคงที่ของก๊าซ (J/(mol*K))
FARADAY = 96485 # ค่าคงที่ฟาราเดย์ (C/mol)
def read_kelvin(self):
"""
อ่านอุณหภูมิในหน่วย Kelvin
ใช้ในสมการ Nernst: E = E0 - (RT/nF)ln(Q)
"""
celsius = self.read_celsius()
return celsius + 273.15
def get_nernst_factor(self, n=1):
"""
คำนวณ 2.303RT/nF ที่อุณหภูมิปัจจุบัน
ค่านี้คือ mV ต่อหน่วย pH (ประมาณ 59.16 mV ที่ 25 C)
"""
T = self.read_kelvin()
return (2.303 * self.R_JOULES * T) / (n * self.FARADAY)การเรียนรู้ OOP ผ่านบอร์ด TitraLab ช่วยให้นิสิตเห็นความเชื่อมโยงระหว่างแนวคิดการเขียนโปรแกรมกับการประยุกต์ใช้ทางเคมี:
| แนวคิดการเขียนโปรแกรม (Programming Concept) | การประยุกต์ใช้ทางเคมี (Chemistry Application) |
|---|---|
| Class และ Object | เหมือนพิมพ์เขียว "บีกเกอร์" กับ บีกเกอร์จริงหลายใบ |
| Class LED | แสดงสถานะการไทเทรต (เขียว = กำลังหยดสาร, แดง = ถึงจุดสมมูล) |
| Class Button | ควบคุมการเริ่ม/หยุดการหยดสาร, ยืนยันการสอบเทียบ |
| Class TemperatureSensor | ชดเชยอุณหภูมิในสมการ Nernst: E = E0 - (2.303RT/nF) x pH |
| Class pHSensor (Week 2) | อ่านค่า mV และแปลงเป็น pH ด้วยเส้นสอบเทียบ |
| Class Pump (Week 2) | ควบคุมการหยดสารไทแทรนต์ด้วย PWM |
| TFT Display | แสดง pH, อุณหภูมิ, กราฟไทเทรชัน (titration curve) |
| Loop/ลูป | วัด pH ซ้ำๆ ทุกวินาทีจนถึงจุดสมมูล |
| Conditional/เงื่อนไข | ตรวจจับจุดสมมูล (equivalence point) จากการเปลี่ยนแปลง pH อย่างรวดเร็ว |
ไฟล์หลักสำหรับการสอน (Core Teaching Files):
| ไฟล์ | คำอธิบาย | บทบาทในการไทเทรต |
|---|---|---|
core/01_led_class.py |
คลาส LED | แสดงสถานะ: เขียว = กำลังทำงาน, แดง = ถึงจุดสมมูล |
core/02_button_class.py |
คลาส Button พร้อม debounce | ควบคุมการเริ่ม/หยุด/ยืนยัน |
core/06_temp_sensor_class.py |
คลาส TemperatureSensor | ชดเชยอุณหภูมิในสมการ Nernst |
core/07_display_basics.py |
พื้นฐานจอ TFT | แสดง pH, กราฟ, เมนู |
core/08_intro_oop.py |
บทนำ OOP (คลาส Beaker) | เข้าใจ Class/Object |
core/09_combined_example.py |
ตัวอย่างรวม Lab Alert | รวมทุก concept |
ไฟล์สำคัญ: ADC และ PWM (Important: ADC and PWM):
| ไฟล์ | คำอธิบาย | เตรียมพร้อมสำหรับ |
|---|---|---|
core/03_adc_ph_basics.py |
ADC 0-4095, สมการ Nernst | เซ็นเซอร์ pH ใน Week 2-3 |
core/04_pwm_pump_basics.py |
PWM Duty cycle, กลยุทธ์ไทเทรชัน | ควบคุมปั๊มใน Week 3 |
core/05_pot_led_dimming.py |
ADC+PWM รวมกัน, value mapping | pH → Pump control loop |
ไฟล์เสริม (Supplementary Files):
| โฟลเดอร์ | คำอธิบาย |
|---|---|
extras/01_procedural/ |
ตัวอย่างแบบ Procedural (ไม่ใช้ OOP) - เปรียบเทียบกับ OOP |
extras/02_advanced_oop/ |
ตัวอย่าง OOP ขั้นสูง - หลาย object, Buzzer class |
extras/03_exercises/ |
แบบฝึกหัดพร้อมเฉลย (starter และ solution) |
extras/04_hardware/DS18B20/ |
ตัวอย่างเซ็นเซอร์อุณหภูมิเพิ่มเติม |
extras/04_hardware/TFT/ |
ตัวอย่างจอ TFT เพิ่มเติม |
extras/04_hardware/Buzzer/ |
ตัวอย่าง Buzzer - แจ้งเตือนจุดสมมูล |
extras/04_hardware/SDCard/ |
ตัวอย่าง SD Card - บันทึกข้อมูลการไทเทรต |
extras/04_hardware/DAC/ |
[เสริม] พื้นฐาน DAC |
extras/05_reference/ |
เอกสารอ้างอิง - อธิบาย self, common mistakes |
extras/archive/07_ADC/ |
[เก็บถาวร] ตัวอย่าง ADC แบบละเอียด |
extras/archive/07_PWM/ |
[เก็บถาวร] ตัวอย่าง PWM แบบละเอียด |
ในสัปดาห์ที่ 2 นิสิตจะนำความรู้จาก Week 1 ไปใช้ในการ สอบเทียบ (Calibration):
| Week 1 (พื้นฐาน) | Week 2 (การประยุกต์ใช้) |
|---|---|
| ADC: อ่านค่า 0-4095 จาก Potentiometer | สอบเทียบ pH: อ่านค่าจากเซ็นเซอร์ pH, สร้างสมการถดถอย |
| PWM: ควบคุม LED ด้วย duty cycle | สอบเทียบปั๊ม: หา flow rate จริง, ตรวจสอบ %RSD |
| เซ็นเซอร์อุณหภูมิ: อ่านค่า °C, K | ชดเชยอุณหภูมิในสมการ Nernst |
| OOP: Class และ Object พื้นฐาน | OOP ขั้นกลาง: Inheritance, Composition |
Week 1: ADC basics (0-4095)
↓
Week 2: สอบเทียบด้วยสารละลายกันชน pH 4, 7, 10
↓
ผลลัพธ์: slope, intercept, R-squared ≥ 0.99
Week 1: PWM basics (duty cycle)
↓
Week 2: วัด flow rate 3-5 ครั้ง, คำนวณ %RSD
↓
ผลลัพธ์: flow_rate (mL/s), %RSD < 5%
หมายเหตุ: ดูรายละเอียดทางเทคนิคเพิ่มเติมที่หัวข้อ "เชื่อมต่อกับสัปดาห์ที่ 2: การประยุกต์ใช้ ADC และ PWM" ด้านบน (หลังหัวข้อ DAC)
ในสัปดาห์ที่ 3 นิสิตจะรวมทุกสิ่งที่เรียนมาเพื่อสร้าง ระบบไทเทรตอัตโนมัติแบบสมบูรณ์:
In Week 3, students integrate all knowledge to build a complete automated titration system:
Week_3/
├── 01_titration_auto.py # โปรแกรมหลัก — ลูปไทเทรตอัตโนมัติ + บันทึกข้อมูล
│ # (ห้ามคัดลอกเป็น main.py! เฟิร์มแวร์รัน main.py อัตโนมัติตอนบูต)
├── titration.py # โมดูลเคมี — โหลดค่าสอบเทียบ + ตรวจจับจุดสมมูล
├── experiment.py # ค่าคงที่การทดลอง (ปริมาตรต่อโดส, ความเข้มข้น ฯลฯ)
├── USER_MANUAL.md # คู่มือผู้ใช้
└── LAB_DIRECTION.md # คู่มือปฏิบัติการ
ไดรเวอร์ฮาร์ดแวร์ (ADC / PWM / OneWire) อยู่ในเฟิร์มแวร์ MicroPad ของบอร์ด — เรียกใช้ผ่าน import scilabpro as slp ส่วนการแสดงผลหลักอยู่บนแอป MicroPad บนแท็บเล็ตผ่าน BLE (จอ TFT บนบอร์ดแสดง dashboard ประกอบ)
| Week 1 (พื้นฐาน) | Week 3 (ระบบเต็มรูปแบบ) |
|---|---|
| ADC Basics | titration.py - อ่านค่า pH ผ่าน slp.read_analog('PH') แล้วแปลง mV เป็น pH ด้วยค่าสอบเทียบ |
| PWM Basics | 01_titration_auto.py - สั่งปั๊มจ่ายไทแทรนต์ผ่าน slp.set_actuator('CONTROL_1', ...) |
| DS18B20 | slp.ds18b20(16) - อ่านอุณหภูมิระหว่างไทเทรต |
| TFT Display | คลาส TitrationUI ใน 01_titration_auto.py - dashboard แสดงผลสด |
| OOP (Class/Object) | คลาส TitrationUI และการแยกโมดูล titration.py + experiment.py |
โค้ดนี้สรุปขั้นตอนหลักของ OOP ใน 4 ขั้นตอน: Import > Define Class > Create Object > Use Object
# 1. Import - นำเข้าโมดูลที่จำเป็น
from machine import Pin
import time
# 2. Define Class - กำหนดคลาส (พิมพ์เขียว)
class LED:
def __init__(self, pin):
"""Constructor - ทำงานเมื่อสร้าง object"""
self._pin = Pin(pin, Pin.OUT)
def on(self):
"""เปิด LED"""
self._pin.value(1)
def off(self):
"""ปิด LED"""
self._pin.value(0)
# 3. Create Object - สร้าง object จากคลาส
led = LED(2) # LED สีแดงที่ GPIO2
# 4. Use Object - ใช้งาน object
try:
led.on()
time.sleep(1)
led.off()
except KeyboardInterrupt:
print("\nหยุดโปรแกรม (Program stopped)")
finally:
led.off() # ปิด LED เมื่อจบโปรแกรม| ภาษาอังกฤษ (English) | ภาษาไทย (Thai) | คำอธิบาย |
|---|---|---|
| Class | คลาส | พิมพ์เขียวสำหรับสร้าง object |
| Object | ออบเจกต์ | สิ่งที่สร้างจากคลาส (instance) |
| Constructor | ตัวสร้าง | method __init__ ที่ทำงานเมื่อสร้าง object |
| Method | เมธอด | ฟังก์ชันที่อยู่ใน class |
| Attribute | แอตทริบิวต์ | ตัวแปรที่อยู่ใน class |
| self | ตัวเอง | ตัวอ้างอิงถึง object ปัจจุบัน |
| ภาษาอังกฤษ (English) | ภาษาไทย (Thai) | คำอธิบาย |
|---|---|---|
| GPIO | จีพีไอโอ | General Purpose Input/Output - ขาอเนกประสงค์ |
| ADC | เอดีซี | Analog-to-Digital Converter - ตัวแปลงสัญญาณแอนะล็อกเป็นดิจิทัล (12-bit, 0-4095) |
| PWM | พีดับเบิลยูเอ็ม | Pulse Width Modulation - การมอดูเลตความกว้างพัลส์ (10-bit, 0-1023) |
| DAC | ดีเอซี | Digital-to-Analog Converter - ตัวแปลงสัญญาณดิจิทัลเป็นแอนะล็อก (8-bit, 0-255) |
| Duty Cycle | ดิวตี้ไซเคิล | สัดส่วนเวลาที่สัญญาณอยู่ที่ HIGH (0-100%) |
| Attenuation | แอทเทนูเอชัน | การลดทอนสัญญาณ (ใช้ตั้งค่าช่วงแรงดัน ADC) |
| Debounce | ดีเบาซ์ | การกำจัดสัญญาณรบกวนจากปุ่มกด |
| ภาษาอังกฤษ (English) | ภาษาไทย (Thai) | คำอธิบาย |
|---|---|---|
| pH | พีเอช | ค่าความเป็นกรด-เบส (-log[H+]) |
| Titration | ไทเทรชัน | การไทเทรต - การหาปริมาณสารด้วยการเติมสารไทแทรนต์ |
| Titrant | สารไทแทรนต์ | สารละลายที่ใช้หยดลงไป (เช่น NaOH) |
| Analyte | สารตัวอย่าง | สารละลายที่ต้องการวิเคราะห์ (เช่น HCl) |
| Equivalence Point | จุดสมมูล | จุดที่สารทำปฏิกิริยาพอดีกัน (pH เปลี่ยนเร็วมาก) |
| Endpoint | จุดยุติ | จุดที่ตรวจวัดได้จริง (อาจต่างจากจุดสมมูลเล็กน้อย) |
| Buffer Solution | สารละลายกันชน | สารละลายที่มี pH คงที่ ใช้สอบเทียบเซ็นเซอร์ |
| Calibration | การสอบเทียบ | การปรับค่าเซ็นเซอร์ให้อ่านค่าถูกต้อง |
| Nernst Equation | สมการเนิร์นสต์ | สมการความสัมพันธ์ระหว่างแรงดันไฟฟ้ากับ pH |
| Slope | ความชัน | ค่า mV/pH จากการสอบเทียบ (ประมาณ -59.16 mV/pH ที่ 25C) |
| Intercept | จุดตัดแกน | ค่าคงที่จากการสอบเทียบ |
TitraLab - 2302311 Integrated Chemistry Laboratory I ภาควิชาเคมี คณะวิทยาศาสตร์ จุฬาลงกรณ์มหาวิทยาลัย Department of Chemistry, Faculty of Science, Chulalongkorn University