การสร้างสัญญาณ พัลส์วิดท์มอดูเลชั่น (PWM) แบบ Phase shitf ด้วย Arduino

This topic will contain a table of contents

…คอนโทรลเลอร์ส่วนใหญ่มีความยืดหยุ่นสูง สามารถเลือกใช้สัญญาณนาฬิกาที่ ความถี่ต่าง ๆ กันได้ ซึ่งความถี่เหล่านี้ได้มาจากวงจรปรีสเกลเลอร์วงจรปรีสเกลเลอร์อาจเป็นวงจร คูณหรือวงจรหารความถี่ก็ได้การคูณ หรือหารความถี่นี้ก็เพื่อให้ได้ความถี่สัญญาณที่ต้องการ โดยปกติจะเป็นวงจรหารความถี่ตัวอย่างเช่น ถ้าสัญญาณนาฬิกาของระบบมีปรีสเกลเลอร์ เป็น 64 ก็หมายความว่าความถี่สัญญาณที่ได้จะเป็น Clk สามารถเลือกใช้ค่าปรีสเกลเลอร์ได้ดัง ตารางที่ 3.1

ตาราง ปรีสเกลเลอร์

image

พอร์ตที่ควบคุมรีจิสเตอร์

…ภายในพอร์ตมีรีจีสเตอร์ที่ทำหน้าที่แตกต่างกันออกไปเช่น การกำหนดโหมดของสัญญาณเปรียบเทียบ การกำหนดสัญญาณเปรียบเทียบให้เป็น Inverting หรือ Non-inverting และการกำหนดค่าปรีสเกลเลอร์ เป็นต้น

image

รูป การกำหนดค่าให้กับ TCCR1A

image

รูป การกำหนดค่าให้กับ TCCR1B

การเลือกโหมดในการสร้างสัญญาณพัลส์วิดท์มอดูเลชั่น

เลือกโหมดในการสร้างสัญาณพัลส์วิดท์มอดูเลชั่น โดยใช้พัลส์วิดท์มอดูเลชั่นโหมด Phase Correct ในการชิฟเฟส ซึ่งเป็นโหมดเดียวที่สร้างรูปคลื่นได้อิสระ จากการเซ็ตค่ารีจีสเตอร์ OCRnX ได้สองครั้ง ในหนึ่งคาบเวลาใช้รีจิสเตอร์สองตัวช่วยกัน ทำให้เฟสชิฟ 180 องศา อาศัยวิธีทางคณิตศาตร์

image

รูป สัญญาณในโหมด Phase Correct

การเลือกค่าปรีสเกลเลอร์

ในการเลือกค่าปรีสเกลเลอร์จากตารางต้องคำนึงถึงค่าสูงสุด (TOP) ด้วย ให้ค่าสูงสุดนับถึงค่าที่เท่าไหร่

นับน้อย - จบเร็ว - ความถี่มาก
นับมาก - จบช้า - ความถี่น้อย

ซึ่งค่าสูงสุดจะเป็นตัวกำหนดความถี่ของสัญญาณพัลส์วิดท์มอดูเลชั่นที่ได้ มีรีจีสเตอร์ที่รับผิดชอบคือ OCRnX พิจารณาค่าสูงสุดจากตารางที่ได้จากสมการที่ 3.40

\bbox[red,5px,border:2px solid blue] { f_OCnxPCPWM = \frac {f_clkl/O} {2*N*TOP} }

ตารางที่ 3.2 พิจารณาค่าสูงสุด

Prescaler f_OCnxPCPWM TOP
8 20kH_z 50
64 20kH_z 6.25
256 20kH_z 1.56
1024 20kH_z 0.36

…จากตาราง 3.2 ในพิจารณาค่าสูงสุด จะเห็นว่าหากเลือกค่าปรีสเกลเลอร์ที่ไม่ใช่ 8 จะได้ค่าสูงสุดเป็นจุดทดนิยมทั้งสิ้นซึ่งในการเลือกนำไปใช้งานค่าสูงสุดมีค่าเป็นจำนวนนับหรือจำนวนเต็ม ดั้งนั้นเลือกค่าปรีสเกลเลอร์ที่หาค่าสูงสุดได้เป็นจำนวนเต็มคือ 8 และจะได้ค่าสูงสุดเท่ากับ 50 จากความถี่ 20 กิโลเฮิรตซ์

การรับค่าแรงดันอินพุต 0 ถึง 5 โวลต์

…ในอาดูโนสามารถรับค่าแรงดันไฟฟ้าแอนะล็อกจากภายนอก 0 ถึง 5 โวลต์ ผ่านพอร์ต (A0) โดยใช้ฟังก์ชั่น analogRead() วงจรแอนะล็อกดิจิทัล (A/D) จะแปลงแรงดันไฟแอนะล็อกเป็นดิจิทัลเพื่ออ่านค่า 0 ถึง 1024

image

รูปที่ 3.19 โปรแกรมรับค่าแรงดัน 0 ถึง 5 โวลต์ ปรับดิวตี้ไซเคิล

…จากรูปที่ 3.19 แสดง โปรแกรมรับค่าแรงดัน 0 ถึง 5 โวลต์ ปรับดิวตี้ไซเคิล เป็นช่วงการทำงานของโปรแกรมทำหน้าที่รับค่าแรงดันป้อนกลับเข้ามาที่พอร์ต A0 แล้วหารด้วย 2.5 เป็นการหารเพื่อทดค่าให้ดิวตี้ไซเคิลมีการตอบสนองไวขึ้น นำค่าที่หารได้มาหาพิกัดความถี่ในช่วง.20 กิโลเฮิรตซ์ โดยการคูณกับค่าสูงสุดแล้วหารด้วยความละเอียดของพอร์ต ADC นำค่าที่ได้มาเข้าสมการทางคณิตศาตร์เพื่อหาสัญญาณเปรียบเทียบเพื่อสร้างสัญญาณพัลส์วิดท์มอดูเลชั่น

การเลือกโหมดในการสร้างสัญญาณพัลส์วิดท์มอดูเลชั่น

เลือกอาดูโน่พัลส์วิดท์มอดูเลชั่น โหมด Phase Correct ในการชิฟเฟส เป็นโหมดเดียวที่สร้างรูปคลื่นได้อิสระ จากการเซ็ตค่า OCRnX ได้สองครั้ง ใน 1 คาบเวลา ใช้รีจิสเตอร์สองตัวช่วยกัน ทำให้ เฟสชิฟ 180˚ ซึ่งการกำหนดโหมดนั้นจะมีการเซตค่ารีจิสเตอร์ 4 ตัว ในโหมด Phase Correct ตามตารางที่ 3.3 พิจารณาโหมดสร้างสัญญาณพัลส์วิดท์มอดูเลชั่น ได้แก่ WGM13 เท่ากับ 1 คือต้องกำหนดในโปรแกรม WGM12 เท่ากับ 0 คือไม่ต้องกำหนดเข้าไปในโปรแกรมก็ได้ WGM11 หรือจะเขียนเป็น CS11 ก็ได้ เท่ากับ 1 คือต้องกำหนดในโปรแกรม และ WGM10 เท่ากับ 0 คือไม่ต้องกำหนดในโปรแกรมก็ได้ ดังรูปที่ 3.20 แสดงการกำหนดโหมด Phase Correct PWM

ตารางที่ 3.3 พิจารณาโหมดสร้างสัญญาณพัลส์วิดท์มอดูเลชั่น

image

image

รูปที่ 3.20 กำหนดโหมด Phase Correct PWM

…พอร์ต 1 หน่วย สามารถออกเอาท์พุตได้ 2 ช่อง (2 ขา) คือ OCRnA และ OCRnB ทำหน้าที่เป็นสัญญาณอ้างอิงนำไปเปรียบเทียบกับสัญญาณเปรียบเทียบว่ามีค่ามากกว่าหรือน้อยกว่า เป็น High หรือ Low เช่น สัญญาณ OCRnA มีค่ามากกว่าสัญญาณเปรียบเทียบให้เป็น Low น้อยกว่าเป็น High และสัญญาณ OCRnB มีค่ามากกว่าสัญญาณเปรียบเทียบให้เป็น High น้อยกว่าเป็น Low จะได้สัญญาณพัลส์วิดท์มอดูเลชั่น รูปที่ 3.21 แสดงการเปรียบเทียบสัญญาณที่เกิดจาก Phase Correct PWM Mode

pwm

รูปที่ 3.21 เปรียบเทียบสัญญาณที่เกิดจาก Phase Correct PWM Mode

การตั้งค่าโปรแกรมโดยใช้ Inverting Mode

image


รูปที่ 3.14 กำหนดสัญญาณแบบ Inverting Mode

เอาต์พุตที่ได้จากโปรแกรมรับแรงดันอินพุต 3 V

image
รูปที่ 3.15 เอาต์พุตของโปรแกรม

*สัญญาณ “สีฟ้า” คือสัญญาณของ OCR1A
*สัญญาณ “สีเหลือง” คือสัญญาณของ OCR1B
เซตโปรแกรมโดยใช้ Non-Inverting Mode

ตาราง 3.5 Compare Output Mode Set Non-Inverting Mode
image

image

รูปที่ 3.16 กำหนดสัญญาณแบบ Non-Inverting Mode

เอาต์พุตที่ได้จากโปรแกรมรับแรงดันอินพุต 3 V

image
รูปที่ 3.17 เอาต์พุตของโปรแกรม

การลิมิตสเกลแรงดันไฟฟ้า

การลิมิตสเกลแรงดันไฟฟ้าที่อ่านได้จากวงจรอนาล็อกทูดิจิตอล (A/D) ให้มีค่าสูงสุด 50 เนื่องจากค่าท๊อปมีค่าสูงสุดอยู่ที่ 50 สมมติ ค่าแรงดันไฟฟ้าที่รับค่ามาเท่ากับ Y ถ้ารับค่าแรงดันไฟฟ้าสูงสุดที่อ่านได้เท่ากับ 1024 อ่านค่าได้ 50 ถ้ารับค่าแรงดันไฟฟ้าสูงสุดที่อ่านได้เท่ากับ Y อ่านค่าได้ (Y⋅50)/1024 แบ่งช่วงให้กับสัญญาณพัลส์วิดท์มอดูเลชั่นทั้งสองช่องโดยหารด้วย 2

image
รูปที่ 3.18 เปรียบเทียบค่าเพื่อสร้างสัญญาณพัลส์วิดท์มอดูเลชั่น

จากรูปภาพที่ 3.18 การแบ่งช่วงกึ่งกลางที่ 25 นั้นจะสังเกตเห็นว่าทางด้านบวกหรือมากกว่า 25 นั้น จะเป็นการเปรียบเทียบเพื่อสัญญาณของช่อง A และทางด้านลบหรือน้อยกว่า 25 จะเป็นการเปรียบเทียบเพื่อสร้างสัญญาณของช่อง B

image
รูปที่ 3.19 เอาต์พุตของโปรแกรม

** การลิมิตค่าดิวตี้ไซเคิล**

เนื่องจากต้องมีการจำกัดค่าดิวตี้ไซเคิลของสัญญาณพัลส์วิดท์ มอดูเลชั่นสองสัญญาณสูงสุดที่ 45% ซึ่งเป็นการป้องกันไม่ให้มอสเฟสสองตัวทำงานพร้อมกันจึงมีการเพิ่มเติมโปรแกรมด้วย “while” ลูป กำหนดเงื่อนไขให้อ่านค่าแรงดันไฟฟ้าที่รับมาหากมีค่าน้อยกว่าค่าที่กำหนดขึ้นให้ทำงานวนอยู่ในลูป “while” จนกว่าค่าแรงดันไฟฟ้าจะมีค่ามากกว่าค่าที่กำหนดให้ออกจากการทำงานในลูป “while” ในที่นี้ แรงดันไฟฟ้า 0.6 V มีค่าประมาณ 422 ในโปรแกรม

image
รูปที่ 3.20 เอาต์พุตของโปรแกรม

โปรแกรมสร้างสัญญาณพัลส์วิดท์มอดูเลชั่น

กำหนดสร้างสัญญาณพัลส์วิดท์ มอดูเลชั่นของสองสัญญาณมีเฟสชิปกัน 180˚ สามารถปรับค่าดิวตี้ไซเคิล จากการแรงดันอินพุต 0 – 5 V ของวงจรพุช–พูล–บูสต์ คอนเวอร์เตอร์ โดยมีเงื่อนไงว่าเมื่อโปรแกรมรับแรงดันมากอินพุตค่าดิวตี้ไซเคิลจะน้อยจนถึง 0 เปอร์เซ็น เมื่อแรงดันเท่ากับหรือเกิน 5 V ขึ้นไป โปรแกรมรับแรงดันอินพุตน้อยค่าดิวตี้ไซเคิลมาก จนถึง 45% เมื่อแรงดันเท่ากับ 0 V


รูปที่ 3.21 โค้ดโปรแกรม

float xxx;
float yyy;
unsigned long pwm1;
unsigned long pwm2;

void setup(){

pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(COM1B0) | _BV(WGM11); 
TCCR1B = _BV(WGM13) | _BV(CS11);
}
void loop(){
	while((analogRead(A1))<250){
	}
while((analogRead(A1))>900){
  OCR1A = 0;
  OCR1B = 0;
	}
ICR1 = 50; 
pwm1 = analogRead(A1); 
pwm2 = analogRead(A1); 
xxx = float(pwm1);
yyy = float(pwm2);
xxx = xxx * ICR1;
yyy = yyy * ICR1;
xxx = xxx / 1024;
yyy = yyy / 1024;
OCR1A = int(28-(xxx/2));
OCR1B = int(23+(yyy/2));
}
2 Likes

พี่ครับถ้าผมต้องการปรับความถี่เป็นทศนิยมแบบละเอียดเวลาแสดงค่าออกที่เอาท์พต ต้องทำยังไงหรอครับ ผมลองเปลี่ยนพรีสเกลแล้วแต่ได้ค่าไม่ตรงถ้าไม่ใช่เลขจำนวนเต็ม

เวลาสัญญาณมันนับ มันนับ 1 2 3 4… ครับ มันจะไม่นับ 1.1 1.2 1.3 ถ้าไม่ฟิกว่าต้องใช้ 2 สัญญาณชิปกัน ก็ใช้คำสั่งสำเร็จรูป gen สัญญาณออกมาจะละเอียดกว่านี้ครับ

คือยังไงหรอครับพี่ ช่วยอธิบายหรือยกตัวอย่างให้ผมหน่อยได้มั้ยครับ

ก็เหมือนที่เราทดสอบว่าเอาจำนวนไม่เต็มไปใส่แล้วสัญญาณมันเพี้ยนนั้นแหละครับ มันนับไม่ได้ตามที่บอก จึงต้องเอาจำนวนเต็มใส่ เวลาสัญญาณนาฬิกามันนับ มันนับได้ มันก็ สร้างสัญญาณออกมาได้

ส่วนเรื่องสร้างสัญญาณอีกแบบโดยใช้คำสั่ง หาเอาในนี้แหละครับ ผมเคยโพสต์เอาไว้แล้วครับ

กรณีชิฟเฟส180องศานี่ คือสัญญาณจะนับแค่จำนวนเต็มอย่างเดียวใช่มั้ยครับพี่ ไม่สามารถนับเป็นทศนิยมได้ใช่มั้ยครับ

ใช่ครับ ใส่แล้วคำนวนสัญญาณออกมาไม่ได้

@Remy_Martin ขอคำแนะนำหน่อยได้ไหมครับ ถ้าผมต้องการสร้าง pwm โดยการรับ สัญญาณ absolute sine แล้วไป compare กับสัญญาณ สามเหลี่ยม 40 kHz ให้ออกมาเป็น pwm พอจะทำได้ไหมอะครับ แล้วต้องทำยังไงหรอครับ

@boss_pong ตั้งกระทู้ใหม่เลยครับ เดียวกระทู้นี้เป็น Referent