[TH] Arduino: ESP32-S2’s DAC&ADC.

หลังจากที่ทดสอบ DAC และ ADC ของทั้ง ESP32, SAM-D21, LGT8F328P และ STM32L432KC เป็นที่เรียบร้อย ครั้งนี้ก็เป็นคราวของ ESP32-S2 ที่ทางเรามีใช้งานอยู่ โดยการทดสอบการทำงานยังคงเป็นเหมือนก่อนหน้านี้ที่ใช้ DAC ส่งคลื่น 3 ลักษณะคือ ฟันปลา สามเหลี่ยม และคลื่นรูปไซน์ออกมา และเขื่อมต่อเข้ากับขาของ ADC เพื่อนอ่านค่า พร้อมทั้งทดสอบดูกราฟว่ามีลักษณะออกมาเป็นอย่างไร

ในการทดลองนี้ได้เชื่อมต่อ DAC1 เข้ากับ ADC ดังภาพที่ 1 โดย ESP32-S2 มี DAC ขนาด 8 บิตจำนวน 2 พอร์ตเรียกว่า DAC1 และ DAC2 ส่วน ADC มีความละเอียด 12 บิต ซึ่งจะเห็นว่ามีคุณสมบัติเหมือนกับ ESP32 แต่จะได้ผลลัพธ์เหมือนกันหรือไม่นั้นคงบอกได้ว่าน่าจะแตกต่างเนื่องจากใช้ไมโครคอนโทรลเลอร์คนละรุ่นกัน โดยใน ESP32-S2 ใช้ตัวเดียวกับ ESP32-S3 ที่มีเพียงแกนเดียว และไม่มี BLE

ภาพที่ 1 บอร์ด Neucleo L432KC เชื่อมต่อขา A3 เข้ากับ D3

ขา DAC มีดังนี้

  • DAC1
  • DAC2

การตั้งค่าสำหรับบอร์ด ESP32-S2 เป็นตามภาพที่ 2

ภาพที่ 2 การตั้งค่าบอร์ดใน Arduino IDE

ตัวอย่างโปรแกรม

ตัวอย่างโปรแกรมวาดกราฟ 3 แบบ คือ กราฟฟันปลา กราฟสามเหลี่ยม และกราฟคลื่นไซน์ มีโค้ดการทำงานดังนี้

กราฟฟันปลา

การสร้างกราฟฟันปลาเป็นการส่งค่า 0 ถึงค่าสูงสุดที่เป็นไปได้ของภาค DAC หลังจากนั้นวนรอบส่งใหม่อีกครั้ง โดยโค้ดสำหรับ ESP32-S2 เป็นดังนี้ และได้ผลลัพธ์ดังตัวอย่างภาพที่ 3

#include <Arduino.h>

#define pinSpk DAC1
#define pinMic 1
#define MAX_DAC_VALUES 200
#define MAX_ADC_VALUES 4096

int adcValue;

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

void loop() {
  for (int i = 0; i < MAX_DAC_VALUES; i++) {
    dacWrite( pinSpk, i );
    adcValue = analogRead(pinMic);
    Serial.println(adcValue);
  }
}
ภาพที่ 3 ตัวอย่างกราฟฟันปลา

กราฟสามเหลี่ยม

กราฟสามเหลี่ยมมีหลักการคล้ายกับฟันปลาด้วยการเพิ่มการวนรอบเพื่อส่งค่ามากสุดกลับมาเป็น 0 ดังโค้ดของ ESP32-S2 ดังต่อไปนี้ และตัวอย่างผลลัพธ์เป็นดังภาพที่ 4

#include <Arduino.h>

#define pinSpk DAC1
#define pinMic 1
#define MAX_DAC_VALUES 200 // 256
#define MAX_ADC_VALUES 4096

int adcValue;

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

void loop() {
for (int i = 0; i < MAX_DAC_VALUES; i++) {
    dacWrite( pinSpk, i );
    adcValue = analogRead(pinMic);
    Serial.println(adcValue);
  }
  for (int i = MAX_DAC_VALUES-1; i >= 0; i--) {
    dacWrite( pinSpk, i );
    adcValue = analogRead(pinMic);
    Serial.println(adcValue);
  }
}
ภาพที่ 4 ตัวอย่างกราฟสามเหลี่ยม

กราฟคลื่นไซน์

การสร้างกราฟคลื่นรูปไซน์ใช้การกำหนดให้มีการวนรอบเพื่อเพิ่มค่ามุมองศาจาก 0 ไปถึง 359 โดยในแต่ละรอบทำสิ่งต่อไปนี้

  1. แปลงค่าองศาเป็นเรเดียน
  2. คำนวณหาไซน์จากมุมเรเดียน
  3. แปลงค่าทศนิยมให้เป็นจำนวนเต็มในช่วงค่าที่ DAC รองรับ
  4. อ่านค่าจาก ADC
  5. ส่งข้อมูลออกทางพอร์ตอนุกรมให้โปรแกรม Serial Plotter

โค้ดสำหรับ ESP32-S2 เป็นดังนี้ และตัวอย่างผลลัพธ์ดังภาพที่ 5

#include <Arduino.h>

#define pinSpk DAC1
#define pinMic 1
#define MAX_DAC_VALUES 200 // 256
#define MAX_ADC_VALUES 4096

int adcValue;

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

void loop() {
  int degree = 0;
  float radian = 0.0;
  float sineValue = 0.0;
  int dValue = 0;

  for (degree = 0; degree < 360; degree++) {
    radian = (float)degree * (2.0 * 3.1415926) / 360.0;
    sineValue = sin(radian);
    dValue = (int)((1.0 + sineValue) * (MAX_DAC_VALUES/2));
    dacWrite( pinSpk, dValue );
    adcValue = analogRead(pinMic);
    Serial.println(adcValue);
  }
}
ภาพที่ 5 ตัวอย่างผลลัพธ์กราฟรูปไซน์

สรุป

จากบทความนี้จะพบว่ากราฟที่ได้จาก ADC ของ ESP32-S2 นั้นแตกต่างจาก ESP32 พอสมควร และดูมีความเป็นเชิงเส้น ส่วนสำหรับการเลือกใช้นั้นต้องดูองค์ประกอบอื่น ๆ ประกอบด้วย เช่น ต้องการคามแม่นยำมากน้อยเพียงไร ต้องการความเร็วในการแปลงสัฐฐาณในระดับใด ต้องเชื่อมต่อเครือข่ายหรือไม่ เป็นต้น สุดท้ายนี้ ขอให้สนุกกับการเขียนโปรแกรมครับ

(C) 2020-2022, โดย อ.ดนัย เจษฎาฐิติกุล/อ.จารุต บุศราทิจ
ปรับปรุงเมื่อ 2021-11-25, 2022-01-27