ผู้เขียน หัวข้อ: การเรียนรู้ครั้งที่ 4 [Basic ESP32] การใช้งาน PWM  (อ่าน 9750 ครั้ง)

admin

  • Administrator
  • Hero Member
  • *****
  • กระทู้: 706
    • ดูรายละเอียด
    • อีเมล์
   การควบคุมพลังงานที่จ่ายให้กับโหลดให้ลดการทำงานลงจากการทำงานปกติ เช่น การลดความสว่างของ LED การลดความเร็วของมอเตอร์ไฟฟ้ากระแสตรง หากใช้วิธีการลดค่าแรงดันที่จ่ายให้ก็สามารถทำได้แต่ผลที่เกิดขึ้นคือจะเกิดกำลังงานสูญเสียไปที่วงจรลดค่าแรงดันนั้น ๆ ซึ่งถ้าหากโหลดใช้กระแสสูงวงจรจะเกิดความเสียหายได้งาน วิธีการแก้ไขคือการเปลี่ยนแปลงจังหวะการส่งกำลังงานให้กับโหลดแทนซึ่งตามจินนาการตามทฤษฎีแล้วจะไม่มีกำลังงานสูญเสียที่วงจรควบคุมเลย การควบคุมลักษณะนี้เป็นการผสมคลื่นทางความกว้างที่เรียกว่า PWM (Pulse Width Modulation) โดยความกว้างของคลื่นจะเปลี่ยนแปลงแต่ความถี่ยังคงเดิม อัตราส่วนระหว่างช่วงคลื่นที่มีแรงดันต่อคาบเวลาคลื่นเรียกว่า Duty cycle ดังรูป


   แต่เนื่องจาก ESP32 ขาพอร์ตไม่มีวงจร PWM โดยตรงมาให้ดังนั้นคำสั่ง analogWrite(); จึงใช้ไม่ได้กับ ESP32 ณ ปัจจุบันนี้ (มกราคม 2019)
  การใช้งานจึงต้องใช้วงจร Timer มาช่วยการทำงานแทนการใช้งาน PWM ใช้การทำงานของ Timer มีฟังก์ชั่นการใช้งานอยู่ 3 ฟังก์ชั่นคือ
   1. ledcSetup(Channel, freq, resolution);   กำหนดค่าการทำงานของวงจรไทเมอร์
   2. ledcAttachPin(GPIO, Channel);            กำหนดขาพอร์ตที่ใช้เชื่อมต่อกับวงจรไทเมอร์
   3. ledcWrite(Channel, dutyCycle);           กำหนดค่า Duty cycle กับวงจรไทเมอร์

วงจรที่ใช้ในการทดลอง
   การเรียนรู้ครั้งนี้เป็นตัวอย่างการใช้งาน PWM ส่งออกขาพอร์ตซึ่งต่อใช้งานให้เป็นตัวอย่างเพียง 4 ขาเท่านั้น การเชื่อมต่อเป็นดังรูป

« แก้ไขครั้งสุดท้าย: มกราคม 17, 2019, 10:21:53 AM โดย admin »

admin

  • Administrator
  • Hero Member
  • *****
  • กระทู้: 706
    • ดูรายละเอียด
    • อีเมล์
Re: ....
« ตอบกลับ #1 เมื่อ: มกราคม 16, 2019, 09:51:02 PM »

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

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

รูปแบบ คำอธิบาย
ledcSetup(channel,freq,resolution); ฟังก์ชั่นกำหนดค่าใน Timer
-channel หมายเลขช่องของ Timer ใช้งานได้ 16 ช่องค่า 0-15
-freq ค่าความถี่ที่ใช้สร้างสัญญาณ PWM
-resolution ค่าความละเอียดของ Duty cycle 1-16 bit
เช่นถ้าใช้ 8 bit ค่า Duty cycle ที่กำหนดจะมีค่า 0-255 หมายถึง 0-100%
ledcAttachPin(GPIO, channel); ฟังก์ชั่นกำหนดขาพอร์ตที่ใช้งานกับช่องของ Timer
-GPIO หมายเลขขาพอร์ตที่ใช้งาน
-channel หมายเลขช่องของ Timer ที่เลือกใช้งานกับขาพอร์ตที่ระบุ
ledcWrite(channel, dutycycle) ฟังก์ชั่นสั่งการให้ Timer สร้างสัญญาณ PWM
-channel หมายเลขช่องของ Timer ที่ต้องการสั่งการ
-dutycycle ค่า Duty cycle ที่ต้องการให้ Timer สร้างขึ้น
หมายเหตุ
   1. หมายเลข pin สามารถใช้ตัวเลข GPIO ได้โดยตรง
   2. ขาพอร์ต GPIO34, GPIO35, GPIO36, GPIO39 ใช้งานได้เฉพาะอินพุทเท่านั้น
« แก้ไขครั้งสุดท้าย: มกราคม 16, 2019, 10:09:13 PM โดย admin »

admin

  • Administrator
  • Hero Member
  • *****
  • กระทู้: 706
    • ดูรายละเอียด
    • อีเมล์
Re: ....
« ตอบกลับ #2 เมื่อ: มกราคม 16, 2019, 10:10:07 PM »
ตัวอย่างโปรแกรม [1]
   เป็นโปรแกรมที่ควบคุมความสว่างของ LED จำนวน 1 ตัวที่ต่ออยู่ที่ขา GPIO21 โดยให้ LED ค่อย ๆ สว่างขึ้นจนสว่างสูงสุดแล้วค่อย ๆ หรี่ลงจนดับสนิท
โค๊ด: [Select]
#define LED1 21
/* setting PWM properties */
const int freq = 5000;
const byte ledChannel = 0;
const byte resolution = 8;
void setup(){
  ledcSetup(ledChannel, freq, resolution);
  ledcAttachPin(LED1, ledChannel);
}
void loop(){
  for(int duty = 0; duty <= 255; duty++){   
    ledcWrite(ledChannel, duty);
    delay(15);
  }
  for(int duty = 255; duty >=0; duty--){   
    ledcWrite(ledChannel, duty);
    delay(15);
  } 
}
ตัวอย่างโปรแกรม [2]
   โปรแกรมไฟวิ่งลักษณะฝนดาวตก โดยเป็นไฟวิ่งที่มีความสว่างต่างกัน การกำหนดความสว่างในโปรแกรมนี้ใช้ resolution ขนาด 8 บิตดังนั้นค่าที่กำหนดความสว่าง (Duty cycle) จะมีค่าระหว่าง 0-255 จะทำให้ LED ดับสนิทจนถึงสว่างสูงสุด การกำหนดความสว่างใช้วิธีสร้างเก็บไว้ในตัวแปรอาเรย์ที่ชื่อว่า fade ดังรูป


เมื่อส่งค่าออกไปยังขาพอร์ตให้ส่งไปที่ละจังหวะเรียงกันไปดังรูป


โค๊ด: [Select]
#define LED1 21
#define LED2 19
#define LED3 18
#define LED4 5
byte fade[] = {0,0,0,0,200,255, 200, 150, 100, 50, 10, 0, 0, 0,0};
void setup() {
  ledcSetup(0, 5000, 8);          /*ledcSetup(Channel,Freq,Resolution)  */
  ledcSetup(1, 5000, 8);
  ledcSetup(2, 5000, 8);
  ledcSetup(3, 5000, 8);
  ledcAttachPin(LED1, 0);         /*ledcAttachPin(Pin,Channel)          */
  ledcAttachPin(LED2, 1);
  ledcAttachPin(LED3, 2);
  ledcAttachPin(LED4, 3);
}
void loop() {
  for (int i = 0; i < 11; i++) {
    ledcWrite(0, fade[i]);
    ledcWrite(1, fade[i + 1]);
    ledcWrite(2, fade[i + 2]);
    ledcWrite(3, fade[i + 3]);
    delay(75);
  }
}
<a href="https://www.youtube.com/v/wXS1C54mV4k" target="_blank" class="new_win">https://www.youtube.com/v/wXS1C54mV4k</a>
« แก้ไขครั้งสุดท้าย: มกราคม 17, 2019, 10:15:34 AM โดย admin »

admin

  • Administrator
  • Hero Member
  • *****
  • กระทู้: 706
    • ดูรายละเอียด
    • อีเมล์
Re: การเรียนรู้ครั้งที่ 4 [Basic ESP32] การใช้งาน PWM
« ตอบกลับ #3 เมื่อ: มกราคม 27, 2019, 03:18:36 PM »
...

admin

  • Administrator
  • Hero Member
  • *****
  • กระทู้: 706
    • ดูรายละเอียด
    • อีเมล์
Re: การเรียนรู้ครั้งที่ 4 [Basic ESP32] การใช้งาน PWM
« ตอบกลับ #4 เมื่อ: มกราคม 27, 2019, 03:18:46 PM »
...