ผู้เขียน หัวข้อ: การเรียนรู้ครั้งที่ 6 [Basic ESP32] การใช้งาน ADC และไลบรารี่ simpleTimer  (อ่าน 3017 ครั้ง)

admin

  • Administrator
  • Hero Member
  • *****
  • กระทู้: 688
    • ดูรายละเอียด
    • อีเมล์
การใช้งาน ADC และการใช้งานไลบรารี่ simpleTimer
   ADC ( analog-to-digital converter) เป็นวงจรแปลงสัญญาณแอนะล็อกเป็นสัญญาณดิจัทัล ESP32 มีขาพอร์ตที่สามารถรับสัญญาณที่เป็นแอนะล็อกได้หลายช่อง (ในขณะที่รับสัญญาณแอนะล็อกจะไม่สามารถใช้งานเป็นพอร์ตปกติได้) วงจร ADC เป็นวงจรขนาด 12 บิตซึ่งจะให้ค่าหลังการแปลงระหว่าง 0-4095 (สามารถกำหนดค่าจำนวนบิตได้ตั้งแต่ 9-12 บิต หากผู้ใช้งานต้องการ)
   การใช้งานไลบรารี่ simpleTimer เป็นเครื่องมือช่วยให้เขียนโปรแกรมที่มีการวนทำงานในเวลาที่แน่นอนสะดวกขึ้นโดยไม่ต้องเขียนโปรแกรมวนทำงานในฟังก์ชั่น void loop()

วงจรที่ใช้ทดลอง


ขาพอร์ต ADC ที่มีใช้งาน


การใช้ฟังก์ชั่นลดทอนสัญญาณ
   ค่าปกติของ ADC เมื่ออ่านค่าที่มีแรงดันประมาณไฟเลี้ยงของวงจรจะได้ค่าการแปลงอยู่ที่ 4096 แต่ผู้ใช้งานสามารถกำหนดการลดทอนสัญญาณได้ 4 ระดับดังรูป

https://espressif-docs.readthedocs-hosted.com/projects/esp-idf/en/v2.1.1/api-reference/peripherals/adc.html

ความเป็นเชิงเส้นของการแปลงในการลดทอนค่าต่าง ๆ

https://www.researchgate.net/figure/ADC-linearity-test-at-12-bit-resolution_fig4_320273388

ตัวอย่างฟังก์ชั่นการใช้งานลดทอนสัญญาณในระดับต่าง ๆ
โค๊ด: [Select]
adc1_config_channel_atten(ADC1_CHANNEL_0,ADC_ATTEN_0db);
adc1_config_channel_atten(ADC1_CHANNEL_0,ADC_ATTEN_2_5db);
adc1_config_channel_atten(ADC1_CHANNEL_0,ADC_ATTEN_6db);
adc1_config_channel_atten(ADC1_CHANNEL_0,ADC_ATTEN_11db);
วงจร ADC
   วงจรแปลงสัญญาณแอนาล็อกมี 2 วงจรแต่ละวงจรก็มีหลายช่องสัญญาณ การกำหนดชื่อขาพอร์ดกับวงจรแปลงสัญญาณเป็นดังรูป   


การใช้งานไลบรารี่ SimpleTimer
   การเขียนโค้ดในหลายกรณีจำเป็นต้องมีการวนไปทำงานตามคาบเวลาที่เหมาะสมอยู่เรื่อย ๆ การเขียนไว้ใน void loop() จะทำให้คาบเวลาในการวนทำงานไม่แน่นอนและทำให้ดูโปรแกรมรก ๆ ไลบรารี่ simpleTimer นี้เป็นทางออกที่ดีโดยสามารถคาบเวลาที่ต้องการให้วนไปทำงานฟังก์ชั่นที่ต้องการได้ค่อนข้างเที่ยงตรงและสะดวกในการใช้งาน ขั้นตอนมีดังนี้

1. ดาวน์โหลดไลบรารี่โดยเข้าไปที่เวปไซต์ https://github.com/jfturcot/SimpleTimer คลิกดาวน์โหลด


2. ทำการติดตั้งไลบรารี่ที่ดาวน์โหลดมา ดำเนินการดังรูป


3. การใช้งานไลบรารี่ ตัวอย่างต้องการให้ทำงานฟังก์ชั่น ReadADC ทุก ๆ 2 วินาที
   (1) เพิ่มไลบรารี่ simpleTimer ลงในโปรแกรม
   (2) ประกาศใช้งานไลบรารี่โดยใช้ชื่อออปเจค (ตัวอย่างนี้ใช้ชื่อว่า timer)
   (3) ฟังก์ชั่นย่อยที่ต้องการให้ทำงาน (ชื่อเดียวกับที่ตั้งค่าไว้)
   (4) ตั้งค่าคาบเวลาและฟังก์ชั่นย่อยที่ต้องการทำงานเมื่อครบเวลาที่กำหนด (ตั้งค่าใน setup)
   (5) ฟังก์ชั่นเริ่มทำงานซึ่งต้องวางไว้ใน loop()

« แก้ไขครั้งสุดท้าย: มกราคม 27, 2019, 06:27:56 PM โดย admin »

admin

  • Administrator
  • Hero Member
  • *****
  • กระทู้: 688
    • ดูรายละเอียด
    • อีเมล์
Re: xxx
« ตอบกลับ #1 เมื่อ: มกราคม 27, 2019, 04:08:45 PM »

ฟังก์ชั่นที่ใช้งานในการทดลองนี้

รูปแบบ คำอธิบาย
pinMode(pin, mode); pin: หมายเลขขาที่ต้องการเซตโหมด
mode: INPUT, OUTPUT, INPUT_PULLUP
digitalWrite(pin,value); pin: หมายเลข ขาที่ต้องการเขียนลอจิกออกพอร์ต
value: ค่าลอจิกที่ต้องการส่งออก HIGH or LOW
analogRead(pin); pin: หมายเลขขาที่ต้องการอ่านสัญญาณแอนนะล็อกเช่น A0, A2, A10,...
delay(ms); ms: ตัวเลขที่หยุดค้างของเวลาหน่วยมิลลิวินาที (unsigned long)

รูปแบบ คำอธิบาย
SimpleTimer object; ประกาศเริ่มใช้งานไลบรารี่ SimpleTimer
ตัวอย่าง ต้องการประกาศใช้งานในออปเจคชื่อว่า timer
SimpleTimer timer;
.setInterval(interval_time, func); ฟังก์ชั่นตั้งค่า (วางไว้ใน void setup())
ตั้งค่าคาบเวลาและฟังก์ชั่นที่ต้องการให้ไปทำงานเมื่อครบเวลา
interval_time= ค่าคาบเวลาหน่วยเป็นมิลลิวินาที
func=ชื่อฟังก์ชั่นที่ต้องการให้ไปทำงานเมื่อครบคาบเวลา
.run(); ฟังก์ชั่นให้ไลบรารี่ทำงาน (วางไว้ใน void loop())
ตัวอย่าง ตั้งชื่อออปเจคว่า timer การใช้งานจะประกาศว่า
timer.run();
หมายเหตุ
   1. หมายเลข pin สามารถใช้ตัวเลข GPIO ได้โดยตรง
   2. ขาพอร์ต GPIO34, GPIO35, GPIO36, GPIO39 ใช้งานได้เฉพาะอินพุทเท่านั้น
« แก้ไขครั้งสุดท้าย: มกราคม 27, 2019, 04:25:25 PM โดย admin »

admin

  • Administrator
  • Hero Member
  • *****
  • กระทู้: 688
    • ดูรายละเอียด
    • อีเมล์
Re: xxx
« ตอบกลับ #2 เมื่อ: มกราคม 27, 2019, 05:00:59 PM »
ตัวอย่าง โปรแกรมอ่านค่าแอนะล็อกพื้นฐาน
   โปรแกรมอ่านค่าสัญญาณแอนะล็อกพื้นฐาน สามารถอ่านได้โดยใช้ฟังก์ชั่น analogRead จากตัวอย่างโปรแกรมเป็นการอ่านจากขา A0 ดังรูป

โค้ด
โค๊ด: [Select]
void setup() {
  Serial.begin(9600);
}
void loop() {
  int adc=analogRead(A0);
  Serial.printf("Value of ADC from A0 :%u \n",adc);
  delay(500);
}
ตัวอย่าง โปรแกรมอ่านค่าแอนะล็อกแบบใช้ฟังก์ชั่นลดทอน
   การอ่านค่าสัญญาณแอนะล็อกแบบต้องการใช้ฟังก์ชั่นลดทอนสามารถทำได้โดย
-เพิ่มไลบรารี่ #include <driver/adc.h>
-ประกาศฟังก์ชั่นลดทอนสัญญาณก่อนคำสั่งอ่านค่าสัญญาณ

ตัวอย่าง โปรแกรมอ่านค่าสัญญาณแอนาล็อกแบบใช้การลดทอน การใช้งานจะต้องประกาศการลดทอนก่อนการอ่านค่าดังรูป

โค้ด
โค๊ด: [Select]
#include <driver/adc.h>
void setup() {
  Serial.begin(9600);     
}
void loop() {
  adc2_config_channel_atten(ADC2_CHANNEL_0,ADC_ATTEN_6db); 
  int adc=analogRead(A10);
  Serial.printf("Value of ADC from A10 :%u \n",adc);
  delay(500);
}
ตัวอย่าง โปรแกรมอ่านค่าสัญญาณแอนาล็อกแบบใช้การลดทอนหลายค่า และอ่านค่าจากช่องสัญญาณช่องเดียวดังรูป

โค้ด
โค๊ด: [Select]
#include <driver/adc.h>
void setup() {
  Serial.begin(9600);     
}
void loop() {
  adc2_config_channel_atten(ADC2_CHANNEL_0,ADC_ATTEN_0db); 
  int adc1=analogRead(A10);
  adc2_config_channel_atten(ADC2_CHANNEL_0,ADC_ATTEN_2_5db); 
  int adc2=analogRead(A10);
  adc2_config_channel_atten(ADC2_CHANNEL_0,ADC_ATTEN_6db); 
  int adc3=analogRead(A10);
  adc2_config_channel_atten(ADC2_CHANNEL_0,ADC_ATTEN_11db); 
  int adc4=analogRead(A10);
  Serial.printf("[0dB:%u][2.5dB:%u][6dB:%u][11dB:%u]\n",adc1,adc2,adc3,adc4);
  delay(500);
}

ตัวอย่าง โปรแกรมอ่านค่าแอนะล็อกควบคุม LED(พื้นฐาน)
   การอ่านค่าสัญญาณแอนะล็อกแล้วนำค่าที่อ่านได้ควบคุมการติดดับของ LED (เขียนแบบวนอ่านค่าสัญญาณ)  จากตัวอย่างโปรแกรมเป็นการอ่านจากขา A0

โค้ด
โค๊ด: [Select]
#define LED1 27
#define LED2 14
#define LED3 12
#define LED4 13
void setup() {
  Serial.begin(9600);
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(LED3, OUTPUT);
  pinMode(LED4, OUTPUT);
}
void loop() {
  int adc = analogRead(A0);
  Serial.printf("Value of ADC from A0 :%u \n", adc);
  digitalWrite(LED1, adc>3500 ? 1 : 0);
  digitalWrite(LED2, adc>2500 ? 1 : 0);
  digitalWrite(LED3, adc>1500 ? 1 : 0);
  digitalWrite(LED4, adc>500 ? 1 : 0);
  delay(500);
}

ตัวอย่าง โปรแกรมอ่านค่าแอนะล็อกควบคุม LED(ใช้ไลบรารี่ simpleTimer)
   การอ่านค่าสัญญาณแอนะล็อกแล้วนำค่าที่อ่านได้ควบคุมการติดดับของ LED เป็นโปรแกรมที่ไม่วนอ่านค่าแต่ใช้ไลบรารี่ simpleTimer กำหนดคาบเวลาให้ไปอ่านค่ามาแทน จากตัวอย่างโปรแกรมเป็นการอ่านจากขา A0

โค้ด
โค๊ด: [Select]
#include <SimpleTimer.h>
const byte ledPin[] = {27, 14, 12, 13};
SimpleTimer timer;
int adc;
void readADC() {
  adc = analogRead(A0);
  Serial.printf("Value of ADC from A0 :%u \n", adc);
}
void setup() {
  Serial.begin(9600);
  for (byte i = 0; i < (sizeof(ledPin) / sizeof(byte)); i++)
    pinMode(ledPin[i], OUTPUT);
  timer.setInterval(1000, readADC);
}
void loop() {
  timer.run();
  digitalWrite(ledPin[0], adc > 3500 ? 1 : 0);
  digitalWrite(ledPin[1], adc > 2500 ? 1 : 0);
  digitalWrite(ledPin[2], adc > 1500 ? 1 : 0);
  digitalWrite(ledPin[3], adc > 500 ? 1 : 0);
  delay(50);
}
« แก้ไขครั้งสุดท้าย: มกราคม 27, 2019, 06:19:42 PM โดย admin »