Unicon04-077128

Page 1

Unicon  77

       ทางผูจัดทําโปรแกรม Arduino IDE ไดจัดเตรียมฟงกชั่นพื้นฐาน เชน ฟงกชั่นเกี่ยวกับขาพอรตอินพุต เอาตพุตดิจิตอล, อินพุตเอาตพุตอะนาลอก เปนตน ดังนันในการเขี ้ ยนโปรแกรมจึงเรียกใชฟงกชันเหล ่ านีได ้ ทันที โดยไมตองใชคําสั่ง #include เพื่อผนวกไฟลเพิ่มเติมแตอยางใด นอกจากฟงกชันพื ่ นฐานเหล ้ านีแล ้ ว นักพัฒนาทานอืนๆ ่ ทีร่ วมในโครงการ Arduino นีก็้ ไดเพิมไลบรารี ่ ่ ด #include อืนๆ ่ เชน ไลบรารีควบคุมมอเตอร, การติดตอกับอุปกรณบัส I2C ฯลฯ ในการเรียกใชงานตองเพิมบรรทั เพือผนวกไฟล ่ ทีเหมาะสมก ่ อน จึงจะเรียกใชฟงกชันได ่ ในบทนี้จะอธิบายถึงการเรียกใชฟงกชั่นและตัวอยางโปรแกรมสําหรับทําการทดลอง โดยใชบอรด Unicon สําหรับวิธีการทดลองสามารถดูไดจากบทที่ 2 ของหนังสือเลมนี้

      4.1.1 คําอธิบายและการเรียกใชฟงกชัน่ 4.1.1.1 pinMode(pin,mode) ใชกําหนดขาพอรตใดๆ ใหเปนพอรตดิจิตอล พารามิเตอร pin - หมายเลขขาพอรตของโมดูล POP-MCU (คาเปน int) ้ mode - โหมดการทํางานเปน INPUT หรือ OUTPUT (คาเปน int) ตองใชตัวพิมพใหญเทานัน ตัวอยางที่ 4-1 int ledPin = 31; void setup() { pinMode(ledPin, OUTPUT); } void loop() { digitalWrite(ledPin, HIGH); delay(1000); digitalWrite(ledPin, LOW); delay(1000); }

// LED connected to Di pin 31

// sets as output

// // // //

LED on waits for a second LED off waits for a second


78 

Unicon

4.1.1.2 digitalWrite(pin,value) สังงานให ่ ขาพอรตทีระบุ ่ ไวมีคาสถานะเปนลอจิกสูง (HIGH หรือ “1”) หรือลอจิกตํ่า (LOW หรือ “0”) พารามิเตอร pin - ขาพอรตของโมดูล POP-MCU value - มีคา HIGH หรือ LOW ตัวอยางที่ 4-2 int ledPin = 31; void setup() { pinMode(ledPin, OUTPUT); } void loop() { digitalWrite(ledPin, HIGH); delay(300); digitalWrite(ledPin, LOW); delay(300); }

// LED connected to Di pin 31

// sets as output

// // // //

LED on waits for 0.3 second LED off waits for 0.3 second

กําหนดใหขา 31 เปน HIGH (มีลอจิกเปน “1”) หนวงเวลา 1 วินาที แลวจึงสั่งใหขา 13 กลับเปน LOW (มีลอจิกเปน “0”) อีกครั้ง

4.1.1.3 int

digitalRead(pin)

อานคาสถานะของขาที่ระบุไววามีคาเปน HIGH หรือ LOW พารามิเตอร ่ องการอานคา ซึงต ่ องเปนขาพอรตดิจิตอล ทําใหมีคาไดจาก 0 ถึง 31 หรือเปนตัว pin - ขาพอรตทีต แปรทีมี่ คาอยูในช  วง 0 ถึง 31 ก็ได คาทีส่ งกลับ เปน HIGH หรือ LOW ตัวอยางที่ 4-3 int ledPin = 31; int inPin = 7; int val = 0; void setup() { pinMode(ledPin, OUTPUT); pinMode(inPin, INPUT); } void loop() { val = digitalRead(inPin); digitalWrite(ledPin, val); }

// LED connected to Di pin 13 // pushbutton connected to digital pin 7 // variable to store the read value

// sets Di 31 as output // sets Di 7 as input

// read input pin // sets the LED to the button’s value

กําหนดใหขา 7 เปนอินพุต สถานะของ LED ทีขา ่ 31 จะเปลียนแปลงตามสถานะของอิ ่ นพุตขา 7


Unicon  79

4.1.2 การทดลองใชงานพอรตเอาตพุตดิจิตอลของ Unicon 4.1.2.1 คุณสมบัติของขาพอรตเอาตพุต สําหรับขาพอรตทีกํ่ าหนดใหเปนเอาตพุตผานทางฟงกชั่น pinMode() จะมีสถานะเปนอิมพีแดนซตํา่ ทําใหสามารถจายกระแสใหกับวงจรภายนอกไดสูงถึง 20mA ซึงเพี ่ ยงพอสําหรับขับกระแสให LED สวาง (อยา ลืมตอตัวตานทานอนุกรมดวย) หรือใชกับตัวตรวจจับตางๆ ได แตไมเพียงพอสําหรับขับรีเลย โซลีนอยด หรือ มอเตอร กอนทีจะใช ่ งานขาดิจิตอลของ Unicon จะตองสั่งกอนวาใหขา Di นีทํ้ าหนาที่เปนอินพุตหรือเอาตพุต ในหัวขอนีจะทดลองต ้ อเปนเอาตพุต ถากําหนดใหเปนเอาตพุตสามารถรับหรือจายกระแสไดสูงสุดถึง 20 mA ซึงเพี ่ ยงพอสําหรับขับ LED

4.1.2.2 การกําหนดโหมดของขาพอรต กอนใชงานตองกําหนดโหมดการทํางานของขาพอรตดิจิตอล ใหเปนอินพุตหรือเอาตพุต กําหนดไดจาก ฟงกชัน่ pinMode()มีรูปแบบดังนี้ pinmode(pin,mode);

เมื่อ pin คือ หมายเลขขาทีต่ องการ Mode คือ โหมดการทํางาน (INPUT หรือ OUTPUT) หลั งจากที่ กําหนดให เป นเอาต พุ ตแล วเมื่ อต องการเขี ยนค าไปยั งขานั้ นๆ ให เรี ยกใช ฟ งกชั่ น digitalWrite() โดยมีรูปแบบดังนี้ digitalWrite(pin,value);

เมื่อ pin คือหมายเลขขาทีต่ องการ value สถานะลอจิกที่ตองการ (HIGH หรือ LOW)

4.1.2.3 ตัวอยางโปรแกรมสั่งให LED กะพริบ ในการทดลองเกียวกั ่ บไมโครคอนโทรลเลอรเรื่องแรก ก็คือ การสั่งใหพอรตทํางานเปนเอาตพุต และ สังให ่ มีคาเปน HIGH หรือ LOW ไดตามที่ตองการ โดยจะตอกับ LED และสั่งให LED ติดดับตอเนืองกั ่ นตลอด เวลา เรียกวา ไฟกะพริบ ในการทดลองขับ LED อยางงาย ไดยกตัวอยางไฟล Blink31 ซึงมี ่ ตัวอยางในโปรแกรม Arduino IDE อยูแลว ในตัวอยางนี้จะนําโปรแกรม Blink31.ino มาประยุกต สั่งเอาตพุตของ Unicon ควบคุม LED สองดวง ใหติดดับสลับกัน เริมต ่ นดวยการตอวงจรสวนของ LED ดังรูปที่ 4-1 (ก) ในรูปจะตอวงจรให LED ทํางานที่ลอจิก 1 คือเมือ่ สังให ่ ขาเปน HIGH จะทําให LED ติด เมือสั ่ งให ่ ขาเปน LOW หลอดจะดับ ในการตอ LED สําหรับบอรด Unicon สามารถใชแผงวงจร ZX-LED ตอตรงกับจุดตอของพอรตไดทันที ดังแสดงในรูปที่ 4-1 (ข) เมื่อตออุปกรณแลว ใหเขียนโปรแกรมตามโปรแกรมที่ 4-1 ทดลองคอมไพล อัปโหลดลงบอรด Unicon ศึกษาผลการทํางาน


80 

Unicon

/* Basic code for turn on LED1 and turn off LED2 for 1 second, * then off LED1 and on LED2 for one second, and so on... * File : TwoLED_Blink.ino */ #define LED1_PIN 11 #define LED2_PIN 13

// LED1 connected to digital pin 11 // LED2 connected to digital pin 13

void setup() { pinMode(LED1_PIN, OUTPUT); pinMode(LED2_PIN, OUTPUT); }

// Run once at startup // Call function pinMode to set Di 11 as OUTPUT // Call function pinMode to set Di 13 as OUTPUT

void loop() { digitalWrite(LED1_PIN, digitalWrite(LED2_PIN, delay(1000); digitalWrite(LED1_PIN, digitalWrite(LED2_PIN, delay(1000); }

// run over and over again HIGH); // Turn on LED1 LOW); // Turn off LED2 // wait 1 second (1000 milisecond) LOW); // Turn off LED1 HIGH); // Turn on LED2

โปรแกรมที่ 4-1 ไฟล TwoLED_Blink.ino โปรแกรมภาษา C ของ Arduino ควบคุมใหบอรด Unicon ขับ LED 2 ดวงกะพริบสลับกัน ZX-LED LED 510 KRC102 S

+

เชื่อมตอดวยสาย JST3AA-8

1

ZX-LED LED 510

Unicon port

KRC102

13

11

S

+

เชื่อมตอดวยสาย JST3AA-8 R2 510 LED2 LED1

ตอวงจรลงบนเบรดบอรด

R1 510

รูปที่4-1 วงจรทดลองดิจิตอลเอาตพุต สังให ่ LED 2 ดวงกะพริบสลับกัน


Unicon  81

ในโปรแกรมตัวอยางที่ 4-1 บรรทัด #define LED1_PIN 11 คือการกําหนดคาคงที่ใหขอความ LED1_PIN มีคาเทากับ 11 หลังจากบรรทัดนี้ในโปรแกรมเมื่อพบขอความ LED1_PIN ใหนําคา 11 ไปแทนที่ แลวจึงคอมไพลโปรแกรม เมื่อโปรแกรมทํางานไดแลว ทดลองแกไขโปรแกรมเพือเปลี ่ ่ยนตําแหนงขาเอาตพุตทีต่ อกับ LED โดย เปลี่ยนคาตัวเลขของบรรทัด #define LED1_PIN 11 เปนคาอื่นๆ ระหวาง 2 ถึง 30 บรรทัด delay(1000); เปนการเรียกใชฟงกชั่น delay() โดยสงคา 1000 ใหกับฟงกชั่น เพื่อให เกิดการหนวงเวลา 1000 มิลลิวินาที (ms) หรือ 1 วินาที ถาตองการปรับให LED กะพริบเร็วขึนหรื ้ อชาลง สามารถ เปลี่ยนคาในวงเล็บเปนคาอื่นๆ ได โดยคายิ่งมาก LED ยิ่งกะพริบชาลง

4.1.2.4 ตัวอยางโปรแกรมไฟวิง่ LED 4 ดวง ในตัวอยางนีจะนํ ้ าบอรด Unicon มาตอควบคุม LED จํานวน 4 ตัว โดยสังให ่ LED ติดตามลําดับ เริมจาก ่ LED1 ไปยัง LED4 แลววนกลับมาเริมที ่ ่ LED1 ตอเนืองตลอดเวลา ่ โดยมีวงจรการตอดังรูปที่ 4-2 และมีโปรแกรม ดังแสดงในโปรแกรมที่ 4-2 ZX-LED LED 510

17

KRC102 + S

ZX-LED LED 510 KRC102 + S

16 1

15 ZX-LED LED 510 KRC102 + S

14

ตอวงจรลงบนเบรดบอรด

14

15

16

17

ZX-LED LED

Unicon port

510

R1-R4 510 x4

KRC102 + S

R4

R3

R2

R1

LED4 LED3 LED2 LED1

รูปที่ 4-2 วงจรไฟวิง่ 4 ดวง


82 

Unicon

/* * Code for turn on and off LED1, LED2, LED3, LED4, and so on.. * File : FourLED_Moving.ino */ #define #define #define #define

LED1_PIN LED2_PIN LED3_PIN LED4_PIN

14 15 16 17

void setup() { pinMode(LED1_PIN, pinMode(LED2_PIN, pinMode(LED3_PIN, pinMode(LED4_PIN, }

// // // //

LED1 LED2 LED3 LED4

connected connected connected connected

to to to to

digital digital digital digital

pin pin pin pin

14 15 16 17

// Run once at startup OUTPUT); OUTPUT); OUTPUT); OUTPUT);

// // // //

Set Set Set Set

Digital Digital Digital Digital

void loop() // run over { digitalWrite(LED1_PIN, HIGH); // Turn on delay(200); // wait for digitalWrite(LED1_PIN, LOW); // Turn off delay(200);

pin pin pin pin

14 15 16 17

as as as as

OUTPUT OUTPUT OUTPUT OUTPUT

and over again LED1 a 0.2 second. (200 ms) LED1

digitalWrite(LED2_PIN, HIGH); // Turn on LED2 delay(200); // wait for a 0.2 second. (200 ms) digitalWrite(LED2_PIN, LOW); // Turn off LED2 delay(200); digitalWrite(LED3_PIN, HIGH); // Turn on LED3 delay(200); // wait for a 0.2 second. (200 ms) digitalWrite(LED3_PIN, LOW); // Turn off LED3 delay(200); digitalWrite(LED4_PIN, HIGH); // Turn on LED1 delay(200); // wait for a 0.2 second. (200 ms) digitalWrite(LED4_PIN, LOW); // Turn off LED1 delay(200); }

โปรแกรมที่ 4-2 ไฟล FourLED_Moving.ino โปรแกรมภาษา C/C++ ของ Arduino เพื่อควบคุมไฟวิง่ LED 4 ดวง การทํางานของโปรแกรมนีเริ ้ ่มดวยการสั่งให LED1 ติด 0.2 วินาที ดับ 0.2 วินาที แลวสังให ่ LED2 ติด 0.2 วินาที ดับ 0.2 วินาที ตามดวย LED3 และ LED4 ติดและดับเปนลําดับวนตอเนืองตลอดเวลา ่ จากโปรแกรมสังให ่ LED ติดตามลําดับดังโปรแกรมที่ 4-2 นํามาเขียนใหม โดยใชตัวแปรอะเรย จะได เปนโปรแกรมที่ 4-3 ผลการทํางานเหมือนกัน แตโปรแกรมที่ 4-3 จะกระชับและเมือคอมไพล ่ แลวไดไฟลภาษา เครืองที ่ ่มีขนาดเล็กกวา


Unicon  83 /* * Code for turn on and off LED1, LED2, LED3, LED4, and so on.. * Same as MovingLED1 but used array. * File : MovingLED_Array.ino * By : Opas Sirikunchittavorn */ #define DELAY_TIME 200 int led_pin[]={14,15,16,17}; int count; void setup() // Run once at startup { for(count=0; count<4; count++) pinMode(led_pin[count], OUTPUT); // Call function pinMode to set Digital pin 14,15,16,17 as OUTPUT } void loop() // run over and over again { for(count=0; count<4; count++) { digitalWrite(led_pin[count], HIGH); // Turn on LED delay(DELAY_TIME); // wait for a 0.2 second. (200 ms) digitalWrite(led_pin[count], LOW); // Turn off LED delay(DELAY_TIME); } }

โปรแกรมที่ 4-3 ไฟล MovingLED_Array.ino โปรแกรมภาษา C/C++ ของ Arduino เพือควบคุ ่ มไฟวิง่ LED แบบใชตัวแปรอะเรย

4.1.3 การทดลองอินพุตดิจิตอลของ Unicon 4.1.3.1 คุณสมบัติของขาพอรตอินพุต ขาพอรตของ Unicon จะถูกกําหนดเปนอินพุตตังแต ้ เริมต ่ น จึงไมจําเปนตองใชฟงกชัน่ pinMode() ใน การกําหนดใหเปนอินพุต ขาพอรตทีถู่ กกําหนดเปนอินพุตจะมีสถานะเปนอิมพีแดนซสูง ทําใหมีความตองการ กระแสไฟฟาจากอุปกรณทีต่ องการอานคาอินพุตนอยมาก ทําใหไมสามารถรับหรือจายกระแสใหกับวงจรภายนอก ทําใหนําขาทีเป ่ นอินพุตนีไปใช ้ งานบางประเภท เชน สรางตัวตรวจจับการสัมผัสทีอาศั ่ ยการวัดคาความจุไฟฟา สําหรับขาอินพุต เมื่อไมมีอินพุตปอนใหจะตองกําหนดคาแรงดันใหแนนอน ทําไดโดยตอตัวตานทาน พูลอัป (pull-up resistor) โดยตอขาของตัวตานทานขาหนึงไปยั ่ งไฟเลี้ยง หรือตอพูลดาวน (pull- down) ซึงต ่ อขา หนึงของตั ่ วตานทานจากขาพอรตลงกราวด คาตัวตานทานที่ใชทั่วไปคือ 10k ดังรูปที่ 4-3 Unicon มีขาพอรตดิจิตอลที่กําหนดใหเปนอินพุตหรือเอาตพุตจํานวน 25 ขา ถาตองการกําหนดเปน ่ รูปแบบดังนี้ อินพุตตองกําหนดดวยฟงกชั่น pinMode และอานคาอินพุตไดจากฟงกชั่น digitalRead ซึงมี digitalRead(pin);

เมื่อ pin คือหมายเลขขาทีต่ องการอานคาสถานะ เมือฟ ่ งกชันทํ ่ างาน จะคืนคาเปนสถานะของขาทีต่ องการอานคา โดยคืนคาเปน LOW (คาเปน “0”) หรือ HIGH (คาเปน “1”)


84 

Unicon

+Vcc

ปกติเปนลอจิกต่ํา (LOW หรือ "0") Rpull-up Di

INPUT

Di

Rpull-down

ปกติเปนลอจิกสูง (HIGH หรือ "1")

(ก) การตอตัวตานทานพูลอัป

INPUT

(ข) การตอตัวตานทานพูลดาวน

รูปที่ 4-3 แสดงการตอตัวตานทานเพือกํ ่ าหนดสภาวะของขาพอรตอินพุตของไมโครคอนโทรลเลอร ในขณะทียั่ งไมมีอินพุตสงเขามา +Vcc

20k

สั่งใหตอตัวตานทาน พูลอัปภายในดวยคําสั่ง digitalWrite(pin, HIGH) Di

Digital input port

รูปที่ 4-4 แสดงการตอตัวตานทานพูลอัปภายในทีขาพอร ่ ตอินพุตดิจิตอลของ POP-MCU ซึงควบคุ ่ มได ดวยกระบวนการทางซอฟตแวร ภายในขาพอรตของไมโครคอนโทรลเลอร ATmega32U4 ซึงเป ่ นไมโครคอนโทรลเลอรหลักของ Unicon จะมีการตอตัวตานทานพูลอัปคา 20k เตรียมไวให ซึงสามารถสั ่ งต ่ อใชงานผานทางซอฟตแวร ดังใน รูปที่ 4-4 สําหรับตัวอยางโปรแกรมเพื่อใชงานมีดังนี้ ตัวอยางที่ 4-4 pinMode(pin, INPUT); digitalWrite(pin, HIGH);

// set pin to input // turn on pullup resistors


Unicon  85

4.1.3.2 ทดลองรับคาสวิตชอยางงาย

Bi-color LED

510

1

เชื่อมตอดวยสาย JST3AA-8

ZX-LED LED 510

Unicon port

KRC102

11

7

S

+

เชื่อมตอดวยสาย JST3AA-8 R1 510

LED1

R2 10k +5V

ตอวงจรลงบนเบรดบอรด

S1

รูปที่ 4-5 วงจรทดสอบการทดลองดิจิตอลอินพุต

ZX-SWITCH

HIGH

S

S

+

+

LOW

10k

G

R

SW.

ในการทดลองนี้จะทดลองอานคาสถานะของสวิตชแบบกดติดปลอยดับ เพื่อควบคุมหลอด LED เมื่อ กดสวิตช S1 ทําให LED1 ติดสวาง เมื่อปลอยสวิตช LED1 จะดับ โดยมีวงจรแสดงไดดังรูปที่ 4-5 และเขียนเปน โปรแกรมไดดังโปรแกรมที่ 4-4 ในการใชงานขาอินพุตดิจิตอลตองตอตัวตานทานพูลอัป (ตอตัวตานทานจากไฟเลียง ้ +5V มายังขาอินพุต) เพือกํ ่ าหนดสถานะทีแน ่ นอนใหกับขาอินพุตในภาวะทีไม ่ มีการกดสวิตช ดังวงจรในรูปที่ 4-5 โดยตอขา 7 ผานตัว ้ +5V เมือไม ่ ไดกดสวิตช SW1 ทีขา ่ 7 จะมีสถานะเปนลอจิกสูงหรือ HIGH หรือ ตานทานคา 10k ไปยังไฟเลียง “1” เมือกดสวิ ่ ตช จะทําใหขา 7 ตอลงกราวด อานคาสถานะเปนลอจิกตําหรื ่ อ LOW หรือ “0”


86 

Unicon

/* * Read input from push button for control status of LED. * Modify from Button (http://www.arduino.cc/en/Tutorial/Button) * File : Button_LED.ino * By : Opas Sirikunchittavorn */ #define LED_PIN #define IN_PIN int val = 0;

11 7

void setup() { pinMode(LED_PIN, OUTPUT); pinMode(IN_PIN, INPUT); } void loop() { val = digitalRead(IN_PIN); if (val == LOW) { digitalWrite(LED_PIN, HIGH); } else { digitalWrite(LED_PIN, LOW); } }

// choose the pin for the LED // choose the input pin (for a pushbutton) // variable for reading the pin status

// declare LED as output // declare pushbutton as input

// read input value // check the input as LOW (button pushed) // turn LED ON

// turn LED OFF

โปรแกรมที่ 4-4 ไฟล Button_LED.ino โปรแกรมภาษา C ของ Arduino สําหรับอานคาอินพุตจากสวิตช แบบปุมกดเพื  อควบคุ ่ ม LED การทํางานของ LED1 จะตรงขามกับสถานะของสวิตชคือ เมือไม ่ กดสวิตช จะอานสถานะของขา 7 ได ลอจิกสูง จึงตองสังให ่ ขา 11 เปนลอจิกตําหรื ่ อ “0” เพือทํ ่ าให LED1 ดับ เมือกดสวิ ่ ตช อานคาสถานะของขา 7 ไดลอจิก “0” ตองสังให ่ ขา 11 เปน “1” เพือขั ่ บ LED1 ติดสวาง เมือโปรแกรมทํ ่ างานไดผลตามทีต่ องการแลว ใหทดลองถอดตัวตานทานพูลอัปคา 10k ออก เพือให ่ ขา 7 ลอย สังเกตกรณีนี้ เมื่อยังไมมีการกดสวิตช LED1 อาจติดกะพริบดวยความเร็วสูง เห็น LED สวางเรื่อๆ เนือง ่ จากสถานะของขา Di7 เปน “0” และ “1” สลับกันไมแนนอน

4.1.3.3 โปรแกรมแกปญหาสัญญาณรบกวนในการกดสวิตชโดยใชซอฟตแวร ในหัวขอนีจะทดลองเขี ้ ยนโปรแกรมรับคาของสวิตช ซึงเป ่ นแบบกดติดปลอยดับ ใหมีการทํางานเปนแบบ กดติดกดดับคือ เมือเริ ่ มต ่ นโปรแกรม LED ดับอยู เมือกดสวิ ่ ตช LED จะติดสวางเมือกดสวิ ่ ตชอีกครัง้ LED จะดับ สลับกันไปมาตลอดเวลา โดยวงจรทีใช ่ ยังเปนวงจรจากรูปที่ 4-5 โดยทั่วไปแลว สวิตชที่ใชจะเปนสวิตชทางกลที่ประกอบดวยหนาสัมผัสโลหะ ในการกดสวิตชใหตอ วงจร พบวาหนาสัมผัสของสวิตชจะไมสัมผัสกันสนิททันที โดยมีชวงเวลาที่เริ่มสัมผัส และหลุดเปนชวงเวลา สันๆ ้ กอนทีหน ่ าสัมผัสของสวิตชจะตออยางสมบูรณ และเมื่อวัดสัญญาณที่ไดจากสวิตชพบวา ระดับสัญญาณ


Unicon  87

+5V

+5V

R1 10k

S1

+5V

R1 10k

PORT

R1 10k

PORT

S1

PORT

S1

+5V

+5V

+5V

0V

0V

0V

สัญญาณรบกวนที่เกิดขึ้น จากการกดสวิตช

สัญญาณรบกวนที่เกิดขึ้น จากการปลอยสวิตช

รูปที่ 4-6 แสดงการเกิดสัญญาณรบกวนเมือมี ่ การกดและปลอยสวิตชในวงจรดิจิตอล มีการสันที ่ เรี่ ยกวา เบาซ (bounce) อยูชั วขณะดั ่ งแสดงในรูปที่ 4-6 โดยระยะเวลาทีสั่ ญญาณเกิดการเบาวซนีมี้ ระยะ เวลาตังแต ้ ไมกีมิ่ ลลิวินาที (ms) ไปจนถึงหลายสิบมิลลิวินาทีขึนกั ้ บประเภทของสวิตชที่ใช การแกปญหาทีระดั ่ บสัญญาณเกิดการสันนี ่ เรี้ ยกวา การดีเบาซ (debounce) หลักการแกไขสัญญาณรบกวน แบบนีคื้ อ หนวงเวลาการเกิดขึนของสั ้ ญญาณพัลสเล็กนอย เพือให ่ วงจรไมสนใจสัญญาณทีเกิ่ ดขึนในช ้ วงเริมต ่ นกดสวิตช ซึงทํ ่ าไดหลายวิธี เชน วิธีการแรก ทําไดโดยใชอุปกรณอิเล็กทรอนิกสพืนฐานอย ้ างตัวตานทานและตัวเก็บประจุ โดยตอกันใน ลักษณะวงจร RC อินติเกรเตอร ดังในรูปที่ 4-7 ดวยวิธีการนี้จะชวยลดผลของสัญญาณรบกวนทีเกิ ่ ดขึ้นจากการ กดสวิตชไดในระดับหนึง่ โดยประสิทธิภาพของวงจรจะขึนกั ้ บการเลือกคาของตัวตานทานและตัวเก็บประจุ หากเลือกคาของตัวเก็บประจุนอยเกินไป อาจไมสามารถลดสัญญาณรบกวนได แตถาเลือกคามากเกินไป จะทําใหความไวในการตรวจจับการกดสวิตชลดลง นันคื ่ อ อาจตองกดสวิตชมากกวา 1 ครั้งเพื่อใหไดสัญญาณ ที่ตองการ +5V R1 10k S1

R2 C1

R3

PORT

วงจร RC อินติเกรเตอร

รูปที่ 4-7 การตอวงจร RC อินติเกรเตอรเพือแก ่ ไขปญหาสัญญาณรบกวนจากการกดสวิตช


88 

Unicon

หรื อถาแกโดยใชไมโครคอนโทรลเลอรจะสามารถแกไขไดกระบวนการทางซอฟตแวร โดยเขียน โปรแกรมให ตรวจจับการเปลียนแปลงระดั ่ บลอจิกของสวิตช ถาพบวามีการเริ่มกดสวิตช ก็คือระดับลอจิก เปลี่ยนจาก “1” เปน “0” โปรแกรมจะหนวงเวลารอจนเลยชวงเวลาเกิดเบาซของสวิตช เมื่อเลยเวลาแลวใหทํา การอานคาสถานะของสวิตชอีกครั้งถายังคงเปน “0” แสดงวา กดสวิตชสมบูรณแลว ระยะเวลาทีต่ องหนวงเวลาหาไดจากการใชออสซิลโลสโคปวัดระดับสัญญาณ หรือใชการทดลองปอน คาหนวงเวลา แลวปรับคาจนกระทังได ่ คาทีแก ่ ปญหาการเบาวซของสวิตชไดอยางสมบูรณ ในโปรแกรมทดลอง ที่ 4-5 ไดทดลองโดยใชคาของการหนวงเวลาเทากับ 10 มิลลิวินาที ซึงสามารถเปลี ่ ่ยนไดที่บรรทัด #define DEBOUNCE 10

ในการทดลองถาใช ZX-SWITCH จะตองเลือกขัวต ้ อที่เขียนวา LOW ซึงเมื ่ ่อยังไมกดสวิตชจะใหเอาต พุตเปนลอจิกสูงหรือ HIGH หรือ “1” เมื่อมีการกดสวิตชจะใหเอาตพุตเปนลอจิกตํ่าหรือ LOW หรือ “0” เมื่อ รันโปรแกรม LED จะเปลี่ยนสถานะเปนตรงขามในทุกครั้งที่กดสวิตช ดังแสดงการทํางานในรูปที่ 4-8 ZX-SWITCH

กดสวิตชเพื่อเปลี่ยน สถานะของ LED S

S

+

LOW

+

HIGH

1

S

+

ZX-LED

LED เปลี่ยนสถานะ เปนตรงขามทุกครั้ง ที่กดสวิตช

รูปที่ 4-8 การทดสอบอินพุตดิจิตอลของ Unicon เมือรั ่ นโปรแกรม DebounceSW.ino


Unicon  89 /* * Read input from push button for control status of LED. * Change operation of push button to togle switch. * File : DebouncedSW.ino * By : Opas Sirikunchittavorn */ #define IN_PIN 7 // the number of the input pin #define OUT_PIN 11 // the number of the output pin #define DEBOUNCE 10 // debounce time = 10 ms int state = HIGH; int reading; int previous = HIGH;

// the current state of the output pin // the current reading from the input pin // the previous reading from the input pin

void setup() { pinMode(IN_PIN, INPUT); pinMode(OUT_PIN, OUTPUT); digitalWrite(OUT_PIN, state); } void loop() { reading = digitalRead(IN_PIN); // if we just pressed the button (i.e. the input went from HIGH to LOW. if (reading == LOW && previous == HIGH) { delay(DEBOUNCE); // wait for decounce if(digitalRead(IN_PIN) == LOW) // if the input remain LOW state = !state; // invert the state of output LED digitalWrite(OUT_PIN, state); } previous = reading; }

โปรแกรมที่ 4-5 ไฟล DebounceSW.ino โปรแกรมภาษา C ของ Arduino อานคาสวิตชเพื่อควบคุม LED แบบมีการแกสัญญาณรบกวนจากการกดสวิตชหรือดีเบาซ


90 

Unicon

   ใชสําหรับสือสารข ่ อมูลระหวางฮารดแวร Arduino กับคอมพิวเตอรหรืออุปกรณอืนๆ ่ โดยจะแบงพอร ตสําหรับเชื่อมตอออกเปน 2 สวนคือ สวนแรกติดตอพอรตอนุกรมเสมือน (virtual COM port) จากการทํางาน ของสวนเชื่อมตอพอรต USB ฟงกชั่นทีใช ่ คือ Serial อีกสวนหนึงคื ่ อ ขาพอรตสื่อสารขอมูลอนุกรมโดยใชขา 0 (RxD) และ 1 (TxD) ฟงกชั่นของ Arduino ที่ใชคือ Serial1 ดังนันเมื ้ อเลื ่ อกใชงานเปนขาพอรตสื่อสารขอมูล อนุกรมแลว จะไมสามารถใชขาพอรต 0 และ 1 เปนพอรตดิจิตอลได ดังแสดงตําแหนงจุดตอพอรตเพื่อใชงาน ของบอรด Unicon ในรูปที่ 4-9

สวนสื่อสารขอมูลอนุกรม UART1 กระทําผาน ขา 0 (TxD) และขา 1 (RxD) ระดับสัญญาณเปนแบบทีทีแอล (0 และ +5V)

สวนสื่อสารขอมูลอนุกรม UART ชุดแรกกระทําผานพอรต USB โดยทํางานผาน พอรตอนุกรมเสมือน (virtual COM port)

1

รูปที่ 4-9 ตําแหนงจุดตอสัญญาณของบอรด Unicon ทีเกี ่ ยวข ่ องกับการทํางานของฟงกชันสื ่ อสารข ่ อมูล อนุกรม Serial และ Serial1 ของ Arduino1.0


Unicon  91

4.2.1 คําอธิบายและการเรียกใชฟงกชัน่ 4.2.1.1 Serial.begin(int

datarate)

กําหนดคาอัตราบอดของการรับสงขอมูลอนุกรมในหนวยบิตตอวินาที (bits per second : bps) ใชคา ตอไปนี้ 300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600 หรือ 115200 พารามิเตอร Int datarate ในหนวยบิตตอวินาที (baud หรือ bps) ตัวอยางที่ 4-5 void setup() { Serial.begin(9600);

// opens serial port, baudrate 9600 bps

}

เปนการเลือกอัตราบอดเทากับ 9600 บิตตอวินาที

4.2.1.2

int Serial.available()

ใชแจงวาไดรับขอมูลตัวอักษร (characters) แลว และพรอมสําหรับการอานไปใชงาน คาทีส่ งกลับจากฟงกชั่น จํานวนไบตทีพร ่ อมสําหรับการอานคา โดยเก็บขอมูลในบัฟเฟอรตัวรับ ถาไมมีขอมูลจะมีคาเปน 0 ถามี ขอมูลฟงกชันจะคื ่ นคาทีมากกว ่ า 0 โดยบัฟเฟอรสามารถเก็บขอมูลไดสูงสุด 128 ไบต ตัวอยางที่ 4-6 int incomingByte = 0; // for incoming serial data void setup() { Serial.begin(9600); // opens serial port, baud rate 9600 bps delay(5000); } void loop() { if (Serial.available() > 0) // send data only when you receive data: { incomingByte = Serial.read(); // read the incoming byte: Serial.print("I received: "); // say what you got: Serial.println(incomingByte, DEC); } }

ในตัวอยางนี้ ใชอัตราบอด 9,600 บิตตอวินาที เมื่อรันโปรแกรมจะตองเปดหนาตาง Serial Monitor เพื่อปอนขอมูลมายังบอรด Unicon ดวย ถามีขอมูลเขามาจะเก็บไวในตัวแปร incomingByte แลวนําไป แสดงที่หนาตาง Serial Monitor โดยตอทายขอความ I received : คาทีแสดงจะเป ่ นคาขอมูลในรูปของ เลขฐานสิบ ยกตัวอยาง หากปอนเลข 2 เขามา จะแสดงขอความ I received : 50 เนื่องจากรหัสแอสกี้ ของ 2 คือ 32 ฐานสิบหก เทากับ 50 ฐานสิบ


92 

Unicon

4.2.1.3 int

Serial.read()

ใชอานคาขอมูลที่ไดรับจากพอรตอนุกรม คาทีส่ งกลับจากฟงกชั่น เปนเลข int ทีเป ่ นไบตแรกของขอมูลทีได ่ รับ (หรือเปน -1 ถาไมมีขอมูล) ตัวอยางที่ 4-7 int incomingByte = 0; // for incoming serial data void setup() { Serial.begin(9600); // opens serial port, baud rate 9600 bps delay(5000); } void loop() { if (Serial.available() > 0) // send data only when you receive data: { incomingByte = Serial.read(); // read the incoming byte: Serial.print("I received: "); // say what you got: Serial.println(incomingByte, DEC); } }

4.2.1.4 Serial.flush() ใชลางบัฟเฟอรตัวรับขอมูลของพอรตอนุกรมใหวาง

4.2.1.5 Serial.print(data) ใชสงขอมูลออกทางพอรตอนุกรม พารามิเตอร ่ ดเศษออกเปนเลขจํานวนเต็ม Data - เปนขอมูลเลขจํานวนเต็ม ไดแก char, int หรือเลขทศนิยมทีตั รูปแบบฟงกชั่น คําสั่งนี้สามารถเขียนไดหลายรูปแบบ Serial.print(b)

เปนการเขียนคําสั่งแบบไมไดระบุรูปแบบ จะพิมพคาตัวแปร b เปนเลขฐานสิบ โดยพิมพตัวอักษรรหัส ASCII ดังตัวอยาง int b = 79; Serial.print(b);

พิมพขอความ 79


Unicon  93 Serial.print(b, DEC)

เปนคําสั่งพิมพคาตัวแปร b เปนตัวเลขฐานสิบ โดยพิมพตัวอักษรตามรหัส ASCII ดังตัวอยาง int b = 79; Serial.print(b);

พิมพขอความ 79 Serial.print(b, HEX)

เปนคําสั่งพิมพคาตัวแปร b เปนตัวเลขฐานสิบหก โดยพิมพตัวอักษรตามรหัส ASCII ดังตัวอยาง int b = 79; Serial.print(b, HEX);

พิมพขอความ 4F Serial.print(b, OCT)

เปนคําสั่งพิมพคาตัวแปร b เปนตัวเลขฐานแปด โดยพิมพตัวอักษรตามรหัส ASCII ดังตัวอยาง int b = 79; Serial.print(b, OCT);

พิมพขอความ 117 Serial.print(b, BIN)

เปนคําสั่งพิมพคาตัวแปร b เปนตัวเลขฐานสอง โดยพิมพตัวอักษรตามรหัส ASCII ดังตัวอยาง int b = 79; Serial.print(b, BIN);

พิมพขอความ 1001111 Serial.print(b, BYTE)

เปนคําสั่งพิมพคาตัวแปร b ขนาด 1 ไบต ดังตัวอยาง int b = 79; Serial.print(b, BYTE);

พิมพตัวอักษร O ซึงมี ่ คาตามตาราง ASCII เทากับ 79 ดูขอมูลจากตารางรหัสแอสกีเพิ ้ มเติ ่ ม Serial.print(str)

เปนคําสั่งพิมพคาขอความในวงเล็บ หรือขอความที่เก็บในตัวแปร str ดังตัวอยาง Serial.print(“Hello World!”);

พิมพขอความ Hello World พารามิเตอร b - ไบตขอมูลทีต ่ องการพิมพออกทางพอรตอนุกรม str - ตัวแปรสตริงทีเก็ ่ บขอความสําหรับสงออกพอรตอนุกรม


94 

Unicon

ตัวอยางที่ 4-8 /* Analog input reads an analog input on analog in 0, prints the value out. created by Tom Igoe */ int analogValue = 0; // variable to hold the analog value void setup() { Serial.begin(9600); // open the serial port at 9600 bps: delay(5000); } void loop() { analogValue = analogRead(0); // read the analog input on pin 0: Serial.print(analogValue); // print it out in many formats: // print as an ASCII-encoded decimal Serial.print("\t"); // print a tab character Serial.print(analogValue, DEC); // print as an ASCII-encoded decimal Serial.print("\t"); // print a tab character Serial.print(analogValue, HEX); // print as an ASCII-encoded hexadecimal Serial.print("\t"); // print a tab character Serial.print(analogValue, OCT); // print as an ASCII-encoded octal Serial.print("\t"); // print a tab character Serial.print(analogValue, BIN); // print as an ASCII-encoded binary Serial.print("\t"); // print a tab character Serial.write(analogValue/4); // print as a raw byte value(divide the value by 4 because // analogRead() returns numbers from 0 to 1023, // but a byte can only hold values up to 255) Serial.print("\t"); // print a tab character Serial.println(); // print a linefeed character delay(10); // delay 10 milliseconds before the next reading }

ตัวอยางนี้แสดงการพิมพขอมูลจากฟงกชัน่ Serial.Print() และ Serial.write() ในรูป แบบตางๆ แสดงผานทางหนาตาง Serial Monitor เทคนิคสําหรับการเขียนโปรแกรม ่ อ คูณเลข Serial.print() จะตัดเศษเลขทศนิยมเหลื อเปนเลขจํานวนเต็ม ทางแกไขทางหนึงคื ทศนิยมดวย 10, 100, 1000 ฯลฯ ขึ้นอยูกับจํานวนหลักของเลขทศนิยม เพื่อแปลงเลขทศนิยมเปนจํานวนเต็ม กอนแลวจึงสงออกพอรตอนุกรม จากนั้นที่ฝงภาครับใหทําการหารคาทีรั่ บไดเพื่อแปลงกลับเปนเลขทศนิยม


Unicon  95

4.2.1.6 Serial.println(data) เปนฟงกชันพิ ่ มพ (หรือสง) ขอมูลออกทางพอรตอนุกรมตามดวยรหัส carriage return (รหัส ASCII หมาย ่ เกิดการเลือนบรรทั ่ ดและขึนบรรทั ้ ด เลข 13 หรือ \r) และ linefeed (รหัส ASCII หมายเลข 10 หรือ \n) เพือให ใหมหลังจากพิมพขอความ มีรูปแบบเหมือนคําสัง่ Serial.print() รูปแบบฟงกชั่น Serial.println(b)

เปนคําสังพิ ่ มพขอมูลแบบไมไดระบุรูปแบบ จะพิมพคาตัวแปรเปนเลขฐานสิบ ตามดวยรหัสอักษร carriage return และ linefeed Serial.println(b, DEC)

เปนคําสังพิ ่ มพคาตัวแปร b เปนตัวเลขฐานสิบ ตามดวยรหัสอักษร carriage return และ linefeed Serial.println(b, HEX)

เปนคําสังพิ ่ มพคาตัวแปร b เปนตัวเลขฐานสิบหก ตามดวยรหัสอักษร carriage return และ linefeed Serial.println(b, OCT)

เปนคําสังพิ ่ มพคาตัวแปร b เปนตัวเลขฐานแปด ตามดวยรหัสอักษร carriage return และ linefeed Serial.println(b, BIN)

เปนคําสังพิ ่ มพคาตัวแปร b เปนตัวเลขฐานสอง ตามดวยรหัสอักษร carriage return และ linefeed Serial.println(str)

พิมพคาในวงเล็บหรือขอความทีเก็ ่ บในตัวแปร str ตามดวยรหัสอักษร carriage return และ linefeed Serial.println()

เปนคําสั่งพิมพรหัส carriage return และ linefeed พารามิเตอร ่ องการพิมพออกทางพอรตอนุกรม b - ไบตขอมูลทีต str - ตัวแปรสตริงทีเก็ ่ บขอความสําหรับสงออกพอรตอนุกรม ตัวอยางที่ 4-9 int analogValue = 0; // void setup() { Serial.begin(9600); // delay(5000); } void loop() { analogValue = analogRead(0); // Serial.println(analogValue); // Serial.println(analogValue, DEC); // Serial.println(analogValue, HEX); // Serial.println(analogValue, OCT); // Serial.println(analogValue, BIN); // delay(10); }

variable to hold the analog value

open the serial port at 9600 bps:

read the print it print as print as print as print as

analog input on pin 0: out in many formats: an ASCII-encoded decimal an hexadecimal an ASCII-encoded octal an ASCII-encoded binary


96 

Unicon

4.2.2 การทดลองใชงาน UART เพือติ ่ ดตอกับคอมพิวเตอร บอรด Unicon ติดตอกับคอมพิวเตอรเพือสื ่ อสารข ่ อมูลอนุกรมผานพอรต USB โดยใชพอรตอนุกรมเสมือน หรื อ virtual COM port ที่เกิดขึ้นจากการทํางานของสวนเชื่อมตอพอรต USB ของไมโครคอนโทรลเลอร ATmega32U4 และไดรเวอร โดยปกติแลวจะเชือมต ่ อพอรตอนุกรมเสมือนผานทางพอรต USB เพื่อติดตอกับ คอมพิ วเตอร ในการอั ปโหลดโปรแกรมเปนหลัก แตก็นํามาใชรับสงขอมูลจากโปรแกรมของผูใชงานกับ คอมพิวเตอรได

4.2.2.1 ฟงกชันที ่ ่เกี่ยวของกับการรับสงขอมูลผานพอรตอนุกรม Arduino1.0x มีฟงกชั่นเกี่ยวกับการรับสงขอมูลผานพอรตอนุกรมมาพรอมใชงาน ดังนี้  Serial.begin(speed) ใชกําหนดอัตราเร็วของการถายทอดขอมูลหรืออัตราบอดหรือบอดเรต  Serial.available() ใชตรวจสอบวามี ขอมูลดานรับหรือไม โดยคืนคาเปน int ตามจํานวน ไบตขอมูลที่รับเขามา  Serial.read(data) ใชอานคาขอมูลจากพอรตอนุกรม  Serial.write(data) ใชเขียนขอมูลไบตไปยังพอรตอนุกรม  Serial.flush() ใชลางบัฟเฟอรทั้งดานรับและสง  Serial.print(data) ใชสงขอมูลออกพอรตอนุกรม  Serial.println(data) ใชสงขอมูลออกพอรตอนุกรมพรอมกับขึ้นบรรทัดใหม

4.2.2.2 ตัวอยางโปรแกรมสงขอมูลออกพอรตอนุกรม เริมต ่ ยดวยการใชฟงกชัน่ Serial.begin() เพือสั ่ งเป ่ ดพอรตอนุกรมและกําหนดอัตราถายทอดขอมูล ที่ใชในการสื่อสารขอมูลหรืออัตราบอด มีรูปแบบการเขียนโปรแกรม ดังนี้ Serial.begin(speed);

เมื่อ speed คืออัตราบอดมีคา 300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600 หรือ 115200 บิตตอวินาที ปกติทีใช ่ คือ 9600 หลังจากเปดพอรต เมือต ่ องการสงขอมูลใหใชฟงกชัน่ Serial.print() หรือ Serial.println() ฟงกชันทั ่ งสองตั ้ วทํางานใหผลคลายกัน ตางกันทีเมื ่ อฟ ่ งกชัน่ Serial.println() สงขอมูลแลว จะขึนบรรทั ้ ด ใหมใหอัตโนมัติ ฟงกชั่น Serial.print()และ Serial.println()มีรูปแบบดังนี้ Serial.print(b,FORMAT);

กับ Serial.println(b,FORMAT);

โดยที่ b คือคาตัวแปรประเภทเลขจํานวนเต็มทีต่ องการสงออกทางพอรตอนุกรม ถาไมระบุรูปแบบ จะพิมพออกเปนรหัส ASCII ของคาตัวแปร FORMAT เปนรูปแบบของการพิมพมี DEC (เลขฐานสิบ), HEX (เลขฐานสิบหก), OCT (เลข ฐานแปด) และ BIN (เลขฐานสอง)


Unicon  97 /* Code for send out data to serial port * File : Serial01.pde * By : Opas Sirikunchiitavorn */ void setup() { Serial.begin(9600); // Set serial port to 9600 bit per second } void loop() { int data = 2345; // print string to serial port Serial.println("Welcome to Arduino1.0 Programming"); // print title Serial.print(data, DEC); // print as an ASCII-encoded decimal Serial.print("\t"); // print a tab character Serial.print(data, HEX); // print as an ASCII-encoded hexadecimal Serial.print("\t"); // print a tab character Serial.print(data, OCT); // print as an ASCII-encoded octal Serial.print("\t"); // print a tab character Serial.print(data, BIN); // print as an ASCII-encoded binary Serial.print("\t"); // print a tab character Serial.write(data); // print as a raw byte value Serial.println(); // print a line feed character delay(1000); // Wait 1 second }

โปรแกรมที่ 4-6 ไฟล Serial01.ino โปรแกรมทดสอบการสงขอมูลออกพอรตอนุกรมเสมือนผานทาง พอรต USB ของบอรด Unicom โปรแกรมที่ 4-6 เปนโปรแกรมทดลองสงขอมูลออกพอรตอนุกรม โดยสงขอความและคาของตัวแปร ในการ ทดลองสงคาตัวแปรจะมีการกําหนดรูปแบบหรือ FORMAT ของคําสัง่ Serial.print() ไวหลายๆ แบบ ในการทดสอบการทํางาน โปรแกรม Arduino IDE จะมีหนาตาง Serial Monitor เพื่ออํานวยความ สะดวกในการรับและสงขอมูลผานพอรตอนุกรม ซึงจะใช ่ พืนที ้ ร่ วมกับพืนที ้ แสดงข ่ อมูล (Text area) ซึงอยู ่ ทาง  ดานลางของหนาตางโปรแกรม Arduino การเปดหนาตางนีทํ้ าไดโดยคลิกที่ปุม Serial Monitor ดังแสดงในรูปที่ 4-10 ในรูปที่ 4-11 แสดงผลการ ทํางานของโปรแกรมที่ 4-6 หลังจากที่อัปโหลดโปรแกรมไปยังบอรด Unicon ่ คือ 2,345 แปลงเปนเลขฐาน 16 คือ 929 เปนเลขฐาน ในโปรแกรมกําหนดคาตัวแปร data=2345 ซึงก็ 8 คือ 4451 เปนเลขฐานสองคือ 100100101001 กรณีที่สังพิ ่ มพโดยใชคําสั่ง Serial.write(data); จะสง คาเปนเลขฐานสอง 8 บิตลาง 00101001 ซึ่งก็คือ 41 ฐานสิบ เทียบเปนรหัส ASCII คืออักขระ ) ที่หนาตางของ Serial Monitor จึงแสดงเปนเครื่องหมาย ) หรือวงเล็บปดนั่นเอง


98 

Unicon

Serial Monitor คลิกเพือเป ่ ดหนาตาง สําหรับรับและสงขอมูล อนุกรมระหวางฮารดแวร Arduino กับคอมพิวเตอร

รูปที่ 4-10 แสดงการเลือกเปดหนาตาง Serial Monitor

รูปที่ 4-11 ผลการทํางานของโปรแกรมที่ 4-6 เมือดู ่ คาผานทาง Serial Monitor


Unicon  99

4.2.2.3 ตัวอยางโปรแกรมรับคาจากพอรตอนุกรมเพื่อกําหนดความเร็วในการกระพริบของ LED ในการรับคาจากพอรตอนุกรมจะใชฟงกชั่น 2 ตัวคือ Serial.avaliable() และ Serial.read() โดยเริ่มจากใชฟงกชัน่ Serial.avaliable()เพือตรวจสอบว ่ ามีขอมูลหรือไม ฟงกชันจะคื ่ นคาเปน เลขจํานวนเต็มแสดงจํานวนขอมูลในบัฟเฟอรตัวรับของพอรตอนุกรม ถาอานคาไดเทากับ 0 แสดงวาไมมีขอมูล เมื่ อทดสอบพบวาฟ งกชั่ น S e r ial .ava lia ble( ) คืนคาไม เท ากับ 0 ถัดมาให ใชฟงกชั่น Serial.read() เพื่ออานคาจากบัฟเฟอรตัวรับ ฟงกชั่นคืนคาเปนเลขจํานวนเต็มที่เปนไบตแรกของขอมูลที่ ไดรับ (หรือเปน -1 ถาไมมีขอมูล) ในตัวอยางนีแสดงตั ้ วอยางการรับคาจากพอรตอนุกรม เพื่อนําคาที่รับไดไปควบคุมอัตราการกระพริบ ของ LED วงจรที่ใชในการทดลองนีแสดงได ้ ดังรูปที่ 4-11 และมีโปรแกรมดังแสดงในโปรแกรมที่ 4-7 มีสวนของโปรแกรมทีควรทราบอยู ่ แห  งหนึงคื ่ อ หากผูพั ฒนาโปรแกรมตองการใหมีการแสดงขอความ บนหนาตาง Serial monitor ของ Arduino1.0 ในทุกครั้งที่เริ่มตนทํางานใหม จะตองหนวงเวลารอใหวงจร USB ภายใน ATmega32U4 ของ Unicon เตรียมความพรอมในการทํางานหรืออีนัมเมอเรชันให ่ เสร็จสมบูรณเสียกอน ดวยการแทรกคําสั่ง delay(5000); กอนใชคําสั่ง Serial.print();

1

ZX-LED LED 510

Unicon port

KRC102

11

S

+

เชื่อมตอดวยสาย JST3AA-8 R1 510

ตอวงจรลงบนเบรดบอรด

LED1

R2 10k

รูปที่ 4-12 วงจรทดสอบการรับขอมูลจากพอรตอนุกรมเพือควบคุ ่ ม LED


100 

Unicon

/* * Code for blinking LED that is received data from serial port * to control rate of blinking. Receive keyboard button 1-5 only. * File : Serial02.pde * By : Opas Sirikunchittavorn */ #define LED1_PIN 11 int incomingByte = 0; int delayTime = 100;

// LED pin as pin 11 // for incoming serial data. // Initial value of delay time.

void setup() { pinMode(LED1_PIN, OUTPUT); // set pin 11 as OUTPUT Serial.begin(9600); // opens serial port at 9600 bps delay(5000); // Delay for USB enumeration Serial.print("Press 1-5 for control speed of LED :"); } void loop() { if (Serial.available() > 0) { incomingByte = Serial.read(); // read the incoming byte: // ASCII '1'=49, '2'=50, '3'=51, '4'=52 and '5'=53 // calculate new delay time if(incomingByte >= 49 && incomingByte <=53) { // echo to user Serial.write(incomingByte); Serial.println(); delayTime=(incomingByte-48)*100; } Serial.print("Press 1-5 for control speed of LED :"); } digitalWrite(LED1_PIN, HIGH); // Turn on LED1 delay(delayTime); // wait for delayTime digitalWrite(LED1_PIN, LOW); // Turn off LED1 delay(delayTime); // wait for delayTime }

โปรแกรมที่ 4-7 ไฟล Serial02.ino โปรแกรมภาษา C ของ Arduino สําหรับทดสอบการรับคาจาก พอรตอนุกรมเพือกํ ่ าหนดความเร็วในการกะพริบของ LED ผลการทํางานของโปรแกรมที่ 4-7 แสดงไดดังรูปที่ 4-13 โปรแกรมนี้จะพิมพขอความ Press 1-5 for control speed of LED : ออกทางพอรตอนุกรม แลวรอใหผูทดลองกดปุม 1 ถึง 5 ทีแป ่ นคียบอรด โดยกด 1 คือให LED ติด 0.1 วินาทีและดับ 0.1 วินาที และถากด 5 จะทําให LED ติด 0.5 วินาทีและดับ 0.5 วินาที ถาไมใชปุม 1 ถึง 5 โปรแกรมจะไมตอบสนอง เมื่อกดแลวโปรแกรมจะสงรหัส ASCII ของปุมนี  ้กลับคืนเพื่อแจงผูทดลอง แลวนําคาทีได ่ ไปคํานวณ คาหนวงเวลาการติดดับของ LED


Unicon  101

1

พิมพขอความทีนี่ ่ 2

คลิกเพื่อสง

รูปที่ 4-13 ผลการทํางานของโปรแกรมที่ 4-7 ที่หนาตาง Serial Monitor ของ Arduino เมื่อตองการสงขอความ ใหพิมพขอความที่ตองการในชองวาง ดานบน เมือพิ ่ มพเสร็จใหคลิกปุม Send คารหัส ASCII ของตัวอักษร 1,2,3,4 และ 5 คือ 49,50,51,52 และ 53 ตามลําดับ ในการคํานวณคา หนวงเวลาของฟงกชั่น delay() ทําไดโดยนําคารหัส ASCII ของตัวอักษรลบดวย 48 แลวนําคาที่ไดคูณดวย 100 ซึงมี ่ สูตรดังนี้ delayTime=(incomingByte-48)*100;

การตรวจจับอินพุตจากการกดปุม 1 ถึง 5 ของผูใชงาน ทําไดโดยใชคําสั่ง if โดยกําหนดเงือนไขดั ่ งนี้ if(incomingByte >= 49 && incomingByte <=53)

เงื่อนไขของคําสั่งนีจะเป ้ นจริงเมื่อคาของขอมูลที่รับไดมากกวาหรือเทากับ 49 และตองนอยกวาหรือ เทากับ 53 จึงจะคํานวณคาหนวงเวลาใหม ถาเปนปุมอื  ่น เงื่อนไขของคําสั่ง if เปนเท็จ จะกําหนดใหขามสวน คํานวณคาหนวงเวลาไป


102 

Unicon

     4.3.1 คําอธิบายและการเรียกใชฟงกชัน่ 4.3.1.1 int

analogRead(pin)

อ านคาจากขาพอรตทีกํ่ าหนดใหเปนอินพุตอะนาลอก Unicon มีวงจรแปลงสัญญาณอะนาลอกเปน ดิจิตอลความละเอียด 10 บิต ทําใหแปลงคาแรงดันอินพุต 0 ถึง +5V ใหเปนขอมูลตัวเลขจํานวนเต็ม ระหวาง 0 ถึง 1,023 พารามิเตอร ่ แทนคา 0 ถึง 11 pin - หมายเลขของขาอินพุตอะนาลอก มีคา 0 ถึง 11 หรือเปนตัวแปรทีใช คาทีส่ งกลับ เลขจํานวนเต็มจาก 0 ถึง 1023 หมายเหตุ สําหรับขาทีเป ่ นอินพุตอะนาลอกไมจําเปนตองประกาศแจงวาเปนอินพุตหรือเอาตพุต ตัวอยางที่ 4-10 int int int int

ledPin = 31; analogPin = 3; val = 0; threshold = 512;

// // // //

LED connected to digital pin 13 potentiometer connected to analog pin 3 variable to store the read value threshold

void setup() { pinMode(ledPin, OUTPUT); } void loop() { val = analogRead(analogPin); if (val >= threshold) { digitalWrite(ledPin, HIGH); } else { digitalWrite(ledPin, LOW); } }

// sets the digital pin 31 as output

// read the input pin

// LED on

// LED off

ตัวอยางนีจะสั ้ งให ่ ขา 31 เปน HIGH เมืออ ่ านคาจากขา analogPin แลวมีคามากกวาหรือเทากับคาเงือนไข ่ ทีกํ่ าหนดไว (ในตัวอยาง คาเงือนไขหรื ่ อ threshold = 255) ทําให LED ทีต่ ออยูติ ดสวาง แตถามีคานอยกวา ขา 31 จะเปน LOW ทําให LED ดับ


Unicon  103

4.3.1.2 analogWrite(pin,

value)

ใชในการเขียนคาอะนาลอกไปยังขาพอรตทีกํ่ าหนดไว เพื่อสรางสัญญาณ PWM พารามิเตอร pin - หมายเลขขาพอรตของโมดูล POP-MCU value - เปนคาดิวตี้ไซเกิลมีคาระหวาง 0 ถึง 255 เมือค ่ าเปน 0 แรงดันของขาพอรตทีกํ่ าหนดจะเปน 0V เมือมี ่ คาเปน 255 แรงดันทีขาพอร ่ ตจะเปน +5V สําหรับคาระหวาง 0 ถึง 255 จะทําใหขาพอรตที่กําหนดไวมีคาแรงดันเปลียนแปลงในย ่ าน 0 ถึง 5V คาทีส่ งกลับจากฟงกชั่น เลขจํานวนเต็มจาก 0 ถึง 255 หมายเหตุ ขาพอรตที่ใชสรางสัญญาณ PWM ดวยฟงกชัน่ analogWrite () ซึงก็ ่ คือ ขา 3, 5, 9, 10 และ 11จะพิเศษจากขาทีเป ่ นพอรตดิจิตอลปกติคือ ไมตองกําหนดคาเพื่อเลือกเปน INPUT หรือ OUTPUT คาความถีของสั ่ ญญาณ PWM มีคาประมาณ 490Hz ่ จะตองเขียนคาดิจิตอล คําสั่ง analogWrite ทํางานกับขา 3, 5, 9, 10, 11 เทานัน้ สําหรับขาอืนๆ เปนกําหนดเปน 0 หรือ 5V ผูใช  งานสามารถนําสัญญาณทีได ่ จากคําสังนี ่ ไปใช ้ ในการปรับความสวางของ LED หรือตอขยายกระแส เพื่อตอปรับความเร็วของมอเตอรได หลังจากเรียกใชคําสั่งนี้ ที่ขาพอรตทีกํ่ าหนดจะมีสัญญาณ PWM สงออก มาอยางตอเนือง ่ จนกวาจะเรียกใชคําสัง่ analogWrite (หรือเรียกคําสัง่ digitalRead หรือ digitalWrite ที่ขาเดียวกัน) ตัวอยางที่ 4-11 int ledPin = 11; int analogPin = 0;

// LED connected to digital pin 11 // potentiometer connected to analog pin 0

int val = 0;

// variable to store the read value

void setup() { pinMode(ledPin, OUTPUT);

// sets the pin as output

} void loop() { val = analogRead(analogPin); // read the input pin analogWrite(ledPin, val / 4); // analogRead values go from 0 to 1023, // analogWrite values from 0 to 255 }

ตัวอยางนี้จะควบคุมความสวางของ LED ที่ตอกับขา 11 ใหเปนไปตามคาทีอ่ านไดจากตัวตานทาน ปรับคาไดทีต่ อกับขา A0 (ตรงกับขา 18)


104 

Unicon

4.3.2 การทดลองอินพุตอะนาลอกของ Unicon ภายในไมโครคอนโทรลเลอร ATmega32U4 บนบอรด Unicon มีวงจรแปลงสัญญาณอะนาลอกเปน ดิจิตอล ความละเอียด 10 บิต จํานวน 12 ชอง ซึงได ่ กําหนดขาตอเปน A0 ถึง A11 วงจรแปลงสัญญาณอะนาลอกเปนดิจิตอลมีความละเอียด 10 บิต ทําหนาที่แปลงแรงดันอินพุต 0 ถึง 5V เปนคาเลขจํานวนเต็ม 0 ถึง 1023 ฟงกชั่นสําหรับอานคาจากอินพุตอะนาลอกคือ analogRead()

โดยคาในวงเล็บคือหมายเลขของชองสัญญาณที่ตองการอานคา (0 ถึง 11) เมื่อฟงกชันทํ ่ างานเสร็จ จะคืนคาเปนเลขจํานวนเต็ม (int) จาก 0 ถึง 1,023 ถาตองการคํานวณเปนคาแรงดันทีมี่ หนวยเปนโวลต (Volt : V) กระทําไดจากความสัมพันธดังนี้ volt = คาทีอ่ านได x 5 /1023

A

A0/18

Unicon port

+5V

VR1 10k

ตอวงจรลงบนเบรดบอรด

รูปที่ 4-14 วงจรทดลองอานคาอินพุตอะนาลอกเพือส ่ งไปแสดงทีคอมพิ ่ วเตอร

A

1

Potentiometer

POTENTIOMETER

ZX-POTV

ZX-POTH


Unicon  105

4.3.2.1 การทดลองอานคาอินพุตอะนาลอกและสงคาออกพอรตอนุกรม ในการทดลองนี้จะตองตอวงจรเพิ่มเติมคือ ตัวตานปรับคาไดที่ตอกับกับไฟเลียง ้ +5V และกราวน โดย มีวงจรดังรูปที่ 4-14 ซึ่งสามารถใชแผงวงจร ZX-POTV หรือ ZX-POTH ตอเขากับบอรด Unicon ไดทันที สําหรับโปรแกรมทดลองแสดงในโปรแกรมที่ 4-8 จากการทํางานของโปรแกรมที่ 4-8 พบวาตัวโปรแกรมจะสงผลการแปลงสัญญาณอะนาลอกซึงก็ ่ คือ คาแรงดันไฟตรงเปนขอมูลดิจิตอลของเลขจํานวนเต็มจาก 0 ถึง 1023 ถาตองการใหสงขอมูลเปนคาของแรงดันในหนวยโวลต (V) ที่มีการแสดงเปนตัวเลขทศนิยมออกทาง พอรตอนุกรม จะตองมีการแกไขโปรแกรมเล็กนอย ดังแสดงโปรแกรมที่แกไขแลวในโปรแกรมที่ 4-9 ในโปรแกรมที่ 4-9 นี้ การคํานวณเพื่อแปลงคาที่อานไดจากอินพุต A0 ใหเปนแรงดัน หากใชสูตร temp = analogValue*4.0/1023;

จะไดคาแรงดันเปนตัวเลขทศนิยม เสร็จแลวใหนําคาที่ไดไปเขาฟงกชั่น sprintf() เพื่อแปลงคาตัว เลขให เปนตัวอักษร จากการทดลองพบวา ฟงกชั่น sprintf() ของ Arduino ไมสามารถใชกับตัวแปรเลข ทศนิยมได จึงตองดัดแปลงสูตรการแปลงคาเปนแรงดัน ดังนี้ temp = analogValue*4.0/1023*1000;

คําตอบที่ไดเปนเลขจํานวนเต็มจาก 0000 (0V) ถึง 5000 (5 V) แลวจึงแปลงเปนขอความและสงออก พอรตอนุกรมทีละตัวอักษร โดยตองใสตําแหนงของจุดทศนิยมใหถูกตอง เมื่อเปรียบเทียบขนาดไฟลที่ไดหลังการคอมไพลของโปรแกรมที่ 4-8 และ 4-9 พบวา ไฟลมีขนาดใหญ ขึนจาก ้ 2,726 ไบต เปน 5,166 ไบต เนืองจากมี ่ การเรียกใชฟงกชั่น sprintf เพื่อแปลงตัวเลขใหเปนขอความ กอน ดังนั้นในการใช งานไมโครคอนโทรลเลอรจึงนิยมสงเปนขอมูลดิบ แลวใหฝงรับซึงก็ ่ คือคอมพิวเตอร นําขอมูลนีไปคํ ้ านวณตอ /* Code for read analog input at An 0 and send to serial port. * File : AnalogIn01.ino * By : Opas Sirikunchittavorn */ #define ANALOG_PIN 0 // Analog input at pin An 0. int analogValue = 0; // Variable for store analog value void setup() { Serial.begin(9600); }

// set serial port at 9600 bps

void loop() { analogValue = analogRead(ANALOG_PIN); Serial.print("Analog input0 = "); Serial.println(analogValue); delay(200); }

// // // //

Read analog input at pin An 0. Send string to serial port. Send analog value to serial port. Delay 0.2 second.

โปรแกรมที่ 4-8 ไฟล AnalogIn01.ino โปรแกรมภาษา C ของ Arduino สําหรับอานคาอินพุต อะนาลอกแลวสงขอมูลทีได ่ จากการแปลงสัญญาณออกไปทีพอร ่ ตอนุกรม


106 

Unicon

รูปที่ 4-15 ผลการทํางานของโปรแกรมที่ 4-8 แสดงผานหนาตาง Serial Terminal ของ Arduino IDE /* * * *

Code for read analog input at An 0, convert to voltage input and send to serial port. File : AnalogIn02.pde (Size after compile 5166 bytes) By : Opas Sirikunchittavorn */

#include <stdio.h> #define ANALOG_PIN 0 int analogValue = 0; void setup() { Serial.begin(9600); }

// include file stdio.h for function sprintf() // Analog input at pin An 0. // variable to store analog value

// set serial port at 9600 bps

void loop() { char str[5]; // Declare string variable int temp; // Temporary variable. analogValue = analogRead(ANALOG_PIN); // Read analog input at pin An 0. temp = analogValue*4.0/1023*1000; // convert to volt and scale *1000 sprintf(str,"%4d",temp); // convert interger to string Serial.print("Analog input0 = "); // print string Serial.print(str[0]); // print voltage in first digit Serial.print("."); if(str[1]==' ') Serial.print("0"); else Serial.print(str[1]); // print voltage in 3rd digit (0.1 volt) if(str[2]==' ') Serial.print("0"); else Serial.print(str[2]); // print voltage in 4th digit (0.01 volt) Serial.print(str[3]); // print voltage in 5th digit (0.001 volt) Serial.println(" Volt"); delay(200); // wait 0.2 second }

โปรแกรมที่ 4-9 ไฟล AnalogIn02.pde โปรแกรมภาษา C ของ Arduinoสําหรับอานคาอินพุตอะนาลอก แลวทําการแปลงเปนคาแรงดันเพือส ่ งออกไปยังพอรตอนุกรม


Unicon  107

รูปที่ 4-16 ผลการทํางานของโปรแกรมที่ 4-9 แสดงผานหนาตาง Serial Terminal ของ Arduino IDE Unicon-Note4/1 แผงวงจรตัวตานทานปรับคาไดแบบแกนหมุน : ZX-POTH และ ZX-POTV ใชกําหนดแรงดัน 0 ถึง +5V ตามการหมุนแกน นําไปใชวัดคามุมและระยะทางได มีแบบตัวตั้งและตัวนอน ให เอาตพุต 2 แบบคือ แรงดันมากขึ้นเมื่อหมุนทวนเข็มนาฬิกา หรือ ตามเข็มนาฬิกา แบบตัวตั้ง

เมื่อหมุนทวนเข็มนาฬิกา แรงดันที่ไ ดจะมากขึ้น

A

POTENTIOMETER

แบบตัวนอน

ZX-POTV/POTH S + S

10kB

+

A

A

Potentiometer

เมื่อหมุนตามเข็มนาฬิกา แรงดันที่ไ ดจะมากขึ้น เมื่อหมุนทวนเข็มนาฬิกา แรงดันที่ไ ดจะมากขึ้น เมื่อหมุนตามเข็มนาฬิกา แรงดันที่ไ ดจะมากขึ้น


108 

Unicon

4.3.2.2 ทดลองอานคาอินพุตอะนาลอกเพือควบคุ ่ มความเร็วในการกะพริบของ LED ในตัวอยางนีเป ้ นการอานคาแรงดันทีขา ่ A0 แลวนําคาทีได ่ จากการแปลงสัญญาณอะนาลอกเปนดิจิตอลของ Unicon ไปปรับความเร็วของการกะพริบของ LED ทีขา ่ 11 ดวยการปรับคาหนวงเวลาของฟงกชัน่ delay()ทํา ให LED ติด-ดับไดนาน 0 ถึง 1.023 วินาที วงจรทดลองแสดงดังรูปที่ 4-18 โปรแกรมทดลองคือโปรแกรมที่ 4-10

A

Potentiometer

ZX-POTH

1

S

+

ZX-LED

11

A0/18

Unicon port

R1 510

LED1

+5V

VR1 10k

ตอวงจรลงบนเบรดบอรด

รูปที่ 4-17 วงจรทีใช ่ ในการอานคาอินพุตอะนาลอกเพือควบคุ ่ มการกะพริบของ LED /* Code for read analog input at An 0, used analog value to control blink rate of LED * By : Opas Sirikunchittavorn */ #define LED1_PIN 2 #define ANALOG_PIN 0 int analogValue = 0;

// LED1 connect at Di 2 // Analog input at pin An 0.

void setup(){ pinMode(LED1_PIN,OUTPUT); } void loop() { analogValue = analogRead(ANALOG_PIN); digitalWrite(LED1_PIN,HIGH); delay(analogValue); digitalWrite(LED1_PIN,LOW); delay(analogValue); }

// read analog input at pin an 0 // Turn on LED1 // delay time = analogValue

โปรแกรมที่ 4-10 ไฟล AnalogIn03.ino สําหรับอานคาอะนาลอกเพือควบคุ ่ มการกะพริบของ LED


Unicon  109

4.3.2.4 การทดลองเอาตพุตอะนาลอกของบอรด Unicon ใน Arduino มีฟงกชัน่ analogWrite() ทําใหสรางสัญญาณอะนาลอกสงออกทางขาพอรตเอาตพุตได โดยอาศัยเทคนิคการสรางสัญญาณ PWM (Pulse Width Modulation) หรือสัญญาณมอดูเลชันทางความกว ่ างพัลส ผูใช  งานสามารถปรับคาดิวตีไซเกิ ้ ลของสัญญาณพัลสไดระหวาง 0 ถึง 255 เมือค ่ าเปน 0 แรงดันของขาพอรตที่ กําหนดไวจะมีคาเปน 0V หากมีคาเปน 255 แรงดันทีขาพอร ่ จะเปน +5V สําหรับคา 0 ถึง 255 จะทําใหขาทีกํ่ าหนด ไวมีคาแรงดันเปลียนแปลงสลั ่ บไปมาระหวาง 0 และ 5V ถามีคาสูง ชวงเวลาทีขาพอร ่ ตนันมี ้ แรงดัน 5V จะนานขึน้ ถาคาเปน 51 สัญญาณพัลสจะมีระดับสัญญาณ +5V เปนเวลานาน 20% ของคาบเวลา และมีแรงดัน 0V นาน 80% ของคาบเวลา หรือมีคาดิวตี้ไซเกิลเทากับ 20%นันเอง ่ ถามีคาเปน 127 สัญญาณพัลสจะมีระดับสัญญาณ +5V เปนเวลานานครึ่งหนึ่งของคาบเวลา และ 0V นานครึ่งหนึ่งของคาบเวลา หรือมีคาดิวตี้ไซเกิล 50% ถามีคาเปน 191 นันคื ่ อ สัญญาณพัลสจะมีระดับสัญญาณ +5V เปนเวลานานสามสวนสี่ ของคาบเวลา และมีแรงดัน 0V นานหนึงส ่ วนสีของคาบเวลา ่ หรือมีคาดิวตี้ไซเกิล 75% ในรูปที่ 4-18 แสดงสัญญาณ PWM ที่คาดิวตี้ไซเกิลตางๆ

20%

50%

75%

รูปที่ 4-18 แสดงสัญญาณ PWM ทีค่ าดิวตี้ไซเกิลตางๆ Unicon-Note4/2 ดิวตี้ไซเกิลของสัญญาณพัลส

tW

คํานวณไดจาก T

t D  w  100% T

โดยที่ tw คือความกวางของพัลส T คือ คาบเวลาของสัญญาณพัลส 1 ลูก การเปลี่ยนแปลงดิวตี้ไซเกิลไมสงผลตอความถีของสั ่ ญญาณแตอยางใด


110 

Unicon

1

S

+

ZX-LED

11

Unicon port

R1 510

LED1

ตอวงจรลงบนเบรดบอรด

รูปที่ 4-19 วงจรทดสอบการทํางานของฟงกชั่น analogWrite() /* Code for fading LED at pin 11 by used analogWrite() function. * By : Opas Sirikunchittavorn */ #define LED_PIN 11 int value = 0;

// LED1 connected to digital pin 11 // variable to keep the actual value

void setup() {} void loop() { for(value = 0 ; value <= 255; value+=5) // fade in (from min to max) { analogWrite(LED_PIN, value); // sets the value (range from 0 to 255) delay(30); // waits for 30 milliseconds to see the dimming effect } for(value = 255; value >=0; value-=5) // fade out (from max to min) { analogWrite(LED_PIN, value); delay(30); } }

โปรแกรมที่ 4-11 ไฟล AnalogOut.ino โปรแกรมภาษา C ของ Arduino สําหรับควบคุมความสวางของ LED ดวยสัญญาณ PWM


Unicon  111

คาแรงดันของสัญญาณพัลสจะไดเปนคาเฉลียของสั ่ ญญาณพัลส ซึงสามารถคํ ่ านวณไดจากความสัมพันธ ทางคณิตศาสตรตอไปนี้ Outout_voltage = (on_time / off_time) * max_voltage เราสามารถนําสัญญาณ PWM ที่ไดจากคําสั่ง analogWrite() นีไปปรั ้ บความสวางของ LED หรือ ตอขยายกระแสเพื่อควบคุมความเร็วของมอเตอรไฟตรงได หลังจากเรียกใชคําสั่งนีแล ้ วขาพอรตทีกํ่ าหนดจะมี สัญญาณ PWM สงออกมาอยางตอเนือง ่ จนกวาจะมีการเรียกใชคําสั่ง analogWrite ในรอบใหม หรือเรียก คําสั่ง digitalRead หรือ digitalWrite ที่ขาพอรตเดียวกัน ฮารดแวร Arduino Leonardo และ Unicon มีขาพอรตทีทํ่ าหนาที่เปนเอาตพุตอะนาลอกได 5 ขา คือ ขา 3, 5, 9, 10 และ 11 การสังให ่ ขาพอรตเปนเอาตพุตอะนาลอก จะตองสังผ ่ านฟงกชัน่ analogWrite() มีรูปแบบดังนี้ analogWrite(pin,value);

เมื่อ pin คือ หมายเลขขาพอรตที่ตองการ (3, 5, 9, 10 และ 11) value คือ คาดิวตี้ไซเกิลทีต ่ องการ คาจาก 0 ถึง 255 การทดลองนีจะสาธิ ้ ตการใชฟงกชั่น analogWrite()โดยมีวงจรทดลองแสดงดังรูปที่ 4-19 สวน โปรแกรมแสดงในโปรแกรมที่ 4-11 โดยกําหนดใหขา 11 ทํางานเปนขาพอรต PWM เพือสร ่ างสัญญาณ PWM ทีมี่ คาดิวตีไซเกิ ้ ลจาก 0 ถึง 255 ทําให LED ทีต่ ออยูมี การติดสวางไลจากดับไปสวางทีสุ่ ด จากนันเปลี ้ ยนค ่ าดิวตีไซเกิ ้ ล เปนจาก 255 ลดลงไปถึง 0 ทําให LED ทีติ่ ดสวางทีสุ่ ด คอยๆ หรีลงจนดั ่ บ จากนันการทํ ้ างานจะวนกลับไปขับ LED ใหติดสวางอีกครัง้

4.3.2.5 การทดลองเอาตพุตอะนาลอกของบอรด Unicon เพือขั ่ บ LED 3 สี อีกหนึงตั ่ วอยางการใชงานเอาตคพุตอะนาลอกสรางสัญญาณ PWM ที่นาสนใจคือ การขับ LED 3 สี RGB (Red, Green, Blue หรือสีแดง, สีเขียว และสีนําเงิ ้ น) เพื่อสรางแสงสีตางๆ จากการผสมของแสงจาก LED แตละสีในตัวถังเดียวกัน แผงวงจร LED 3สีทีใช ่ ในการทดลองนีคื้ อ ZX-LED3C แผงวงจรไฟแสดงผลหลายสี มีหนาตา ของบอรดแสดงในรูปที่ 4-20 และวงจรสมบูรณ ZX-LED3C แสดงในรูปที่ 4-21 ใช LED แมสีแสง 3 สีคือ สีแดง, ้ นทีบรรจุ ่ รวมอยูในตั  วถังเดียวกัน มีขา จุดรับสัญญาณขับ เขียว และนําเงิ LED สีน้ําเงิน รวมเปนขาแคโทด ในการแสดงผลสามารถผสมให เกิดแสงสีตางๆ ไดดวยการปอนแรงดันไฟตรงเขาที่ จุดรับสัญญาณขับ ชองอินพุตสีแดง (R - Red), เขียว (G - Green) และนํา้ LED สีแดง เงิน (B - Blue) ดวยแรงดันทีป่ อนใหแก LED ทัง้ 3 ่ างกันจะทําให LED เปลงแสงสีทีเกิ ่ ดจาก รูปที่ 4-20 แผงวงจร ZX-LED3C และจุดตอสัญญาณ ตัวทีแตกต การผสมกันของ LED 3 สีทีอยู ่ ภายใน 

จุดรับสัญญาณขับ LED สีเขียว O

GREEN BLUE RED


112 

Unicon

+V Q4 KRA102 (DTA114)

RED

Q6 KRA102 (DTA114)

Q5 KRA102 (DTA114)

Q1 KRC102 (DTC114)

Q2 KRC102 (DTC114)

GREEN

RG 330

RR 680

LED1 RGB Common Cathode

Q3 KRC102 (DTC114)

BLUE

R

G

RB 510

B

รูปที่ 4-21 วงจรของ ZX-LED3C แผงวงจรไฟแสดงผลหลายสี

ตอวงจรลงบนเบรดบอรด 13

1

5

11

Unicon port

R2 R3 510 330 G B R

R1 680 LED1 RGB

com

สัญญาณ PWM สําหรับขับ LED สีเขียว

11

5

ZX-LED3C

13

O GREEN BLUE RED

สัญญาณ PWM สําหรับขับ LED สีน้ําเงิน

สัญญาณ PWM สําหรับขับ LED สีแดง

รูปที่ 4-22 วงจรทดลองขับ LED 3 สีดวยสัญญาณ PWM โดยใชบอรด Unicon


Unicon  113 // Init the Pins used for PWM const int redPin = 13; // const int greenPin = 11; // const int bluePin = 5; // int Level; // int LevelR; // int LevelG; // int LevelB; // void setup() { // Set all LED pin as output pinMode(redPin, OUTPUT); pinMode(greenPin, OUTPUT); pinMode(bluePin, OUTPUT); analogWrite(redPin, 200); delay(300); Level=0; }

Set pin Set pin Set pin Declare Declare Declare Declare

13 for driving the red LED 11 for driving the green LED 13 for driving the blue LED the level counter the red LED level variable the green LED level variable the blue LED level variable

// Start witg red color 0.3 second // Clear counter

void loop() { Level++; // LevelR = Level + 200; // LevelG = Level; // LevelB = Level; // analogWrite(redPin, LevelR); // analogWrite(bluePin, LevelB); // analogWrite(greenPin, LevelG);// delay(50); if (Level > 255) // { Level = 0; // analogWrite(redPin, 200); // delay(300); } }

Increase counter Define red LED level Define green LED level Define blue LED level Send PWM signal to red LED Send PWM signal to blue LED Send PWM signal to green LED Check maximum value of PWM Clear counnter Drive red LED again

การทํางานของโปรแกรม เริ่มตนดวยการกําหนดใหขาพอรตที่ใชในการขับ LED เปนเอาตพุตดวยคําสั่ง pinMode จากนัน้ ขับ LED ใหแสดงสีแดง แลวเขาสูลูปของโปรแกรมเพื่อเริมต ่ นผสมแสงสีอืนเข ่ าไป ดวยการปอนสัญญาณ PWM ไปยังจุดตอรับสัญญาณของ LED แตละสี โดยใชคําสั่ง analogWrite โดยวนปอนคาสําหรับแสง สีเขียวและนําเงิ ้ น ตังแต ้ 0 ถึง 255 ในการทํางานจริง จะเห็น LED ขับแสงสีแดง ครูหนุ  งจากนันจะเริ ้ ่มเปลียน ่ เปนสีเขียว เขียวอมฟา จนกลายเปนสีขาว แลววนกลับมาเปนสีแดงเพื่อเรีมรอบการแสดงผลใหม ่

โปรแกรมที่ 4-12 ไฟล PWM_LED3C.ino โปรแกรมภาษา C/C++ ของ Arduino สําหรับขับ LED 3 สี ดวยสัญญาณ PWM


114 

Unicon

LED แตละสีมีวงจรขับแยกกันอิสระ ซึงใช ่ ทรานซิสเตอรเบอร KRA102 และ KRC102 ทํางานรวม กัน ตัวตานทานทีใช ่ ในการจํากัดกระแสของ LED แตละสีจะแตกตางกัน ทังนี ้ เพื ้ อให ่ เมือป ่ อนแรงดัน +5V ใหแก LED ทั้ง 3 สีแลว จะทําใหเกิดการรวมแสงสีเปนแสงสีขาว วงจรทดลองแสดงในรูปที่ 4-22 และโปรแกรมสําหรับทดสอบแสดงในโปรแกรมที่ 4-12 การทํางาน หลักๆ ของโปรแกรมคือ สรางสัญญาณ PWM ที่มีคาดิวตี้ไซเกิลตางกัน เพื่อนําไปขับ LED แตละสี เพื่อใหได แสงสีตามที่ตองการ

4.3.2.6 การตรวจสอบขาของ LED 3 สี 4 ขา ในกรณีที่ทําการทดลองโดยใช LED 3 สี 4 ขาแบบปกติ จะตองทําการตรวจสอบขาของ LED กอน เนืองจาก ่ LED 3 สี 4 ขานีมี้ การจัดขาที่แตกตางกันไปในแตละผูผลิต ทั้งยังแตกตางกันทังชนิ ้ ดแอโนดรวมกับ แคโทดรวม (1) ตรวจสอบกอนวา LED 3 สีที่ใชเปนแบบแอโนดรวมหรือแคโทดรวม โดยตอขารวมหรือขาคอม มอน (common) ซึงเป ่ นขาที่ยาวสุดเขากับไฟเลี้ยง +3V หรือ +3.3V หรือ +5V ตองตออนุกรมกับตัวตานทาน ประมาณ 330 ถึง 510 กอน เพื่อจํากัดกระแสไฟฟาไมใหไหล ผาน LED มากเกินไป รวมถึงปองกันในกรณีที่ ตอกลับขั้วดวย จากนั้นใหตอขาที่เหลือเขากับกราวดทีละขา ดังรูป

(1.1) ถา LED ติดสวางในการตอทุกขา สรุปไดวา LED ตัวนันๆ ้ เปนแบบแอโนดรวม ใหตรวจสอบ ตอวาขาใดเปน ขาแคโทดของ LED สีใด (1.2) ถา LED ติดจากการตอคูใดคู  หนึ  ง่ อาจเปนเพราะตําแหนงขารวมผิด โดยขาที่ตอเขากับกราวด แลว LED ติด อาจเปนขาแคโทดรวม (1.3) ถา LED ไมติดเลยในทุกกรณี ใหทําตอในขันตอนที ้ ่ (2)


Unicon  115

(2) ตอขารวมเขากับกราวดผานตัวตานทานประมาณ 330 ถึง 510 สวนขาที่เหลือตอกับ +3V หรือ +3.3V หรือ +5V โดยใหตอทีละขา เพื่อดูวา LED ติดหรือไม (ติดเปนสีใดก็ได)

(2.1) ถา LED ติดสวางในการตอทุกขา สรุปไดวา LED ตัวนั้นๆ เปนแบบแคโทดรวม ใหตรวจ สอบตอวาขาใดเปนขาแอโนดของ LED สีใด (2.2) ถา LED ติดจากการตอคูใดคู  หนึ  งเท ่ านัน้ (ติดกรณีเดียว) อาจเกิดจากตําแหนงขารวมผิด โดย ขาที่ตอเขากับไฟเลี้ยงแลวทําให LED ติด อาจเปนขาแอโทดรวม (2.3) ถา LED ไมติดเลยในทุกกรณี ใหกลับไปทําในขั้นตอนที่ (1)ใหมอีกครั้ง หรืออาจสรุปไดวา LED ตัวนั้นๆ เสียหายไปแลว

4.3.2.7 การทดลองใชงานอินพุตและเอาตพุตอะนาลอกของบอรด Unicon เพือขั ่ บ LED 3 สี ในตัวอยางการทดลองตอไปนี้ เปนการใชงานอินพุตอะนาลอกเพื่อรับสัญญาณมาควบคุมการทํางาน ของเอาตคพุตอะนาลอกใหสรางสัญญาณ PWM ตามการเปลียนแปลงค ่ าของอินพุต โดยเอาตพุตของวงจรตอ เขากับ LED 3 สี หรือแผงวงจร ZX-LED3C ดังแสดงวงจรในรูปที่ 4-23 ดานอินพุตอะนาลอกของบอรด Unicon ที่ชอง A0, A1 และ A2 ใหตอเขากับ ZX-POTH หรือ ZX-POTV หรือตัวตานทานปรับคาได จํานวน 3 ตัว โปรแกรมสําหรับทดลองแสดงในโปรแกรมที่ 4-13


116 

Unicon

รูปที่ 4-23 วงจรทดลองขับ LED 3 สีดวยสัญญาณ PWM โดย รับการกําหนดคาจากสัญญาณ อินพุตอะนาลอก


Unicon  117 // Init the Pins used for PWM const int redPin = 13; const int greenPin = 11; const int bluePin = 5; // Init the Pins used for 10K pots const int redPot = 0; const int greenPot = 1; const int bluePot = 2; // Init our Vars int RedValue; int GreenValue; int BlueValue; void setup() { pinMode(redPin, OUTPUT); pinMode(greenPin, OUTPUT); pinMode(bluePin, OUTPUT); } void loop() { // Read the voltage on each analog pin then scale down to 0 to 255 RedValue = (map(analogRead(redPot), 0, 1023, 0, 255)); BlueValue = (map(analogRead(bluePot), 0, 1023, 0, 255)); GreenValue = (map(analogRead(greenPot), 0, 1023, 0, 255)); // Write the color to each pin using PWM analogWrite(redPin, RedValue); analogWrite(bluePin, BlueValue); analogWrite(greenPin, GreenValue); }

การทํางานของโปรแกรม เริ่มตนดวยการกําหนดใหขาพอรตที่ใชในการขับ LED เปนเอาตพุตดวยคําสั่ง pinMode จากนัน้ อานคาของสัญญาณอินพุตอะนาลอกจากขา A0 ถึง A2 แลวทําการปรับคาจาก 0 ถึง 1023 เปนคา 0 ถึง 255 ดวยคําสั่ง map แลวนํามาเก็บไวในตัวแปร RedValue, GreenValue และ BlueValue ตามลําดับ จากนันทํ ้ าการสรางสัญญาณ PWM ออกไปยังขาเอาตพุตอะนาลอกทัง้ 3 ขา ดวยคําสัง่ analogWrite ดังนั้น LED จะขับแสงสีตางๆ ตามสัญญาณ PWM ทีเปลี ่ ่ยนแปลงตามการปรับคาของตัวตานทาน ทีอิ่ นพุตอะนาลอก

โปรแกรมที่ 4-13 ไฟล PWM_AnalogLED3C.ino โปรแกรมภาษา C/C++ ของ Arduino สําหรับขับ LED 3 สีดวยสัญญาณ PWM ทีเปลี ่ ยนแปลงตามสั ่ ญญาณอินพุตอะนาลอก


118 

Unicon

   4.4.1

unsigned long millis()

คืนคาเปนคาเวลาในหนวยมิลลิวินาที นับตังแต ้ Unicon เริ่มรันโปรแกรมปจจุบัน คาทีส่ งกลับจากฟงกชั่น คาเวลาในหนวยเปนมิลลิวินาทีตั้งแตเริมรั ่ นโปรแกรมปจจุบัน คืนคาเปน unsigned long คาตัวเลข จะเกิดการโอเวอรโฟลว (คาเกินแลวกลับเปนศูนย) เมื่อเวลาผานไปประมาณ 9 ชัวโมง ่ ตัวอยางที่ 4-12 long time; void setup() { Serial.begin(9600); } void loop() { Serial.print("Time: "); time = millis(); Serial.println(time); delay(1000);

//prints time since program started // wait a second so as not to // send massive amounts of data

}

4.4.2

delay(ms)

เปนฟงกชั่นชะลอการทํางานหรือหนวงเวลาของโปรแกรมตามเวลาที่กําหนดในหนวยมิลลิวินาที พารามิเตอร ่ องการหนวงเวลา หนวยเปนมิลลิวินาที (1000 ms เทากับ 1 วินาที) ms - ระยะเวลาทีต ตัวอยางที่ 4-13 int ledPin = 31; void setup() { pinMode(ledPin, OUTPUT); } void loop() { digitalWrite(ledPin, HIGH); delay(1000); digitalWrite(ledPin, LOW); delay(1000); }

// LED connected to pin 31

// sets as output

// // // //

LED on waits for a second LED off waits for a second

จากตัวอยางนี้ กําหนดให pin หมายเลข 31 เปนเอาตพุต สั่งใหเปน HIGH (LED ติด) หยุดรอ 1000 มิลลิวินาที (1 วินาที) แลวสั่งเปน LOW (LED ดับ) แลวหยุดรอ 1000 มิลลิวินาที


Unicon  119

4.4.3

delayMicroseconds(us)

เปนฟงกชั่นชะลอการทํางานหรือหนวงเวลาของโปรแกรมตามเวลาที่กําหนดในหนวยไมโครวินาที พารามิเตอร us - คาหนวงเวลาในหนวยไมโครวินาที (1000 ไมโครวินาที = 1 มิลลิวินาที และหนึ่งลานไมโครวินาที = 1 วินาที) ตัวอยางที่ 4-16 int outPin = 11;

// digital pin 11

void setup() { pinMode(outPin, OUTPUT);

// sets as output

} void loop() { digitalWrite(outPin, HIGH); delayMicroseconds(50);

// sets the pin on // pauses for 50 microseconds

digitalWrite(outPin, LOW);

// sets the pin off

delayMicroseconds(50);

// pauses for 50 microseconds

}

จากตัวอยางนี้ กําหนดใหขา 11 ทํางานเปนเอาตพุตเพื่อสงสัญญาณพัลสทีมี่ คาบเวลา 100 ไมโคร วินาทีตอเนื่องตลอดเวลา ผูทดลองสามารถอัปโหลดโปรแกรมนี้ไปยังบอรด Unicon เพื่อทดสอบการทํางาน โดยใชออสซิลโล สโคปตอวัดสัญญาณทีจุ่ ดตอพอรต 11 ของ Unicon ดังในรูปที่ 4-24 คําเตือน ฟงกชั่ นนี้สามารถทํางานอยางแมนยําในชวงตั้งแต 3 ไมโครวินาทีขึ้นไป ไมสามารถประกันไดวา delayMicroseconds จะทํางานไดอยางเทียงตรงสํ ่ าหรับคาหนวงเวลาทีตํ่ ่ากวานี้ เพื่ อใหหนวงเวลาไดอยางแมนยํา ฟงกชั่นนีจะหยุ ้ ดการทํางานของอินเตอรรัปต ทําใหการทํางาน บางอยาง เชน การรับขอมูลจากพอรตอนุกรม หรือการเพิมค ่ าทีจะส ่ งกลับคืนโดยฟงกชัน่ milis() จะไมเกิดขึน้ ดังนันควรจะใช ้ ฟงกชันนี ่ สํ้ าหรับการหนวงเวลาสันๆ ้ ถาตองการหนวงเวลานานๆ แนะนําใหใชฟงกชัน่ delay() แทน


120 

Unicon

ขากราวด (GND)

1

จายไฟ +6V ไมเกิน +9V

ขา 11

สายตอกราวด ปลายปากคีบจับสายตอกราวด

สายวัดของออสซิลโลสโคป

สายกราวด

รูปสัญญาณทีได ่ จากการวัดดวยออสซิลโลสโคป จะพบวา ไดคาบเวลา 108 ไมโครวินาที ซึ่ง คลาดเคลือนจากที ่ ่กําหนดไวในโปรแกรมเล็กนอย

รูปที่ 4-24 แสดงการวัดสัญญาณทีจุ่ ดตอพอรตของบอรด Unicon ในการทดสอบฟงกชันหน ่ วงเวลา


Unicon  121

4.4.4 การทดลองใชงานฟงกชันหน ่ วงเวลาในการสรางสัญญาณเสียง การสรางเสียงเพื่อขับลําโพงที่เปนขดลวดหรือลําโพงแบบเปยโซ ตัวไมโครคอนโทรลเลอรจะตอง สรางสัญญาณกระแสสลับทีกระแสไฟฟ ่ าสามารถไหลกลับทิศได จึงตองใชสัญญาณจากไมโครคอนโทรลเลอร 2 เสน หรือถาตองการประหยัดจะใชสัญญาณเพียงเสนเดียวก็ได แตตองตอตัวเก็บประจุอนุกรมกับขาเอาตพุตที่ ใชขับสัญญาณเสียงดวย ในการทดลองนีจะสร ้ างเสียงความถี่ 1kHz ออกที่ลําโพงเปยโซนาน 0.5 วินาที แลวเงียบ 0.5 วินาที สลับกันตลอดเวลา โดยใชวงจรในรูปที่ 4-25 และเขียนโปรแกรมไดดังโปรแกรมที่ 4-14 อุปกรณที่เพิ่มเขามาในการทดลองนี้คือ ZX-SPEAKER แผงวงจรลําโพงเปยโซ มีวงจรภายในแสดงใน รูปที่ 4-26 สวนดานการเขียนโปรแกรม ในการทดลองนี้มีเปาหมายคือ สรางสัญญาณเสียงความถี่ 1kHz สัญญาณ จึงมีคาบเวลาเทากับ 1 มิลลิวินาที ดังนันจะต ้ องทําใหสัญญาณทีส่ งไปยังลําโพงเปยโซมีระดับสัญญาณเปนลอจิก สูงหรือ HIGH หรือ “1” เปนเวลา 500 ไมโครวินาที และเปนลอจิกตํ่าหรือ LOW หรือ “0” นาน 500 ไมโคร วินาที สลับกันตอเนือง ่ ทําไดโดยใชคําสั่งดังนี้ digitalWrite(PIEZO_PIN,HIGH); delayMicroseconds(500); digitalWrite(PIEZO_PIN,LOW); delayMicroseconds(500);

ตอวงจรลงบนเบรดบอรด Unicon port

11 C1 10F

1

SPEAKER

รูปที่ 4-25 วงจรทดลองสรางสัญญาณเสียงดวยฟงกชันหน ่ วงเวลาของ Arduino

S

+

+ S

O

SP1 Piezo


122 

Unicon

K1 SOUND + S

C1 10/16V

       ใชลําโพงเปยโซ มีอิมพีแดนซ 32  มีคาความถีเรโซแนนซ ่ ในยาน1 ถึง 3kHz

SP1 Piezo speaker

 รับสัญญาณอินพุตไดสูงสุด 5Vp-p

รูปที่ 4-26 หนาตา, วงจร และขอมูลทางเทคนิคของ ZX-SPEAKER แผงวงจรลําโพงเปยโซ /*********************************************************** * Program drive piezo speaker to sound at 1kHz 0.5 sec and off 0.5 sec. * File : Sound1kHz.ino * By : Opas Sirikunchittaworn ***********************************************************/ #define PIEZO_PIN 11 void setup() { pinMode(PIEZO_PIN,OUTPUT); // Piezo speaker at pin 3 } void loop() { int i; for(i=0;i<500;i++) { digitalWrite(PIEZO_PIN,HIGH); delayMicroseconds(500); digitalWrite(PIEZO_PIN,LOW); delayMicroseconds(500); } delay(500); // off buzzer 0.5 second. }

โปรแกรมที่ 4-14 ไฟล Sound1kHz.ino โปรแกรมภาษา C/C++ ของ Arduino สําหรับทดลองสราง สัญญาณเสียงอยางงายกับบอรด Unicon ในโปรแกรมตองการใหเสียงความถี่ 1kHz ดังนาน 0.5 วินาที แสดงวาตองใหสัญญาณเกิดขึ้น 500 ลูก for() ดังนี้ ดังนันส ้ วนของโปรแกรมดานบนจะตองทํางาน 500 ครัง้ ซึงในโปรแกรมทํ ่ าไดโดยใชคําสังวนรอบ ่ for(i=0;i<500;i++)

เมื่อตองการใหเงียบ 0.5 วินาทีทําไดโดยใชคําสั่ง delay(500);


Unicon  123

   ใชระบุวาเมื่อเกิดการอินเตอรรัปตจากภายนอกจะใหโปรแกรมกระโดดไปยังฟงกชั่นใด

4.5.1

attachInterrupt(interrupt, function, mode)

ใชระบุวา เมื่อขาอินพุตที่รับสัญญาณอินเตอรรัปตจากภายนอกมีการเปลี่ยนแปลงเกิดขึ้น จะกําหนดให ซีพียูกระโดดไปยังฟงกชันใด ่ โดยบอรด Unicon มีขาอินพุตรับสัญญาณอินเตอรรัปตจากภายนอก 4 ขาคือ INT0 ถึง INT3 ซึงตรงกั ่ บขา 3, 2, 0 และ 1 ตามลําดับ ซึงใช ่ งานรวมกับขา SCL และ SDA (ขาสัญญาณสําหรับติดตอ อุปกรณระบบบัส I2C), RxD, TxD (ขารับสงขอมูลอนุกรม UART1)

 INT0 : 3/SCL INT2 : 0/RxD

INT1 : 2/SDA INT3 : 1/TxD

1

หมายเหตุ ฟงกชันที ่ ่ทํางานเมื่อการอินเตอรรัปตจะไมสามารถเรียกใชฟงกชัน่ milis() และ delay() ได เมื่อ เกิดการตอบสนองอินเตอรรัปตแลว ดังนั้นขอมูลทีเข ่ ามาทางขา serial data อาจสูญหายได พารามิเตอร Interrupt - หมายเลขของชองอินพุตอินเตอรรัปต (เปน int) ่ จะกระโดดไปทํ ่ างานเมือเกิ ่ ดอินเตอรรัปต ฟงกชันนี ่ ต้ องไมรับคาพารามิเตอรและ function - ฟงกชันที ไมมีการคืนคา


124 

Unicon

- เลือกประเภทสัญญาณทีใช ่ กระตุนใหเกิดการอินเตอรรัปต LOW เกิดอินเตอรรัปตเมื่อขาสัญญาณเปนลอจิก “0” CHANGE เกิดอินเตอรรัปตเมื่อมีการเปลียนแปลงลอจิ ่ ก RISING เกิดอินเตอรรัปตเมือมี ่ การเปลียนลอจิ ่ ก “0” เปน “1” FALLING เกิดอินเตอรรัปตเมือมี ่ การเปลียนลอจิ ่ ก “1” เปน “0” ตัวอยางที่ 4-14 mode

int pin = 31; volatile int state = LOW; void setup() { pinMode(pin, OUTPUT); attachInterrupt(0, blink, CHANGE); } void loop() { digitalWrite(pin, state); } void blink() { state = !state; }

ตัวอยางนี้เลือกอินพุตอินเตอรรัปตชอง 0 กําหนดใหกระโดดไปทํางานที่ฟงกชัน่ blink เพื่อเปลี่ยน สถานะลอจิกที่ขา 31 เมื่อเกิดการอินเตอรรัปตจากการเปลี่ยนแปลงลอจิกที่ขา INT0 หรือ SCL หรือขา 3

4.5.2

detachInterrupt(interrupt)

ยกเลิกการอินเตอรรัปต พารามิเตอร Interrupt - หมายเลขของชองอินพุตอินเตอรรัปตทีต ่ องการยกเลิก (คาเปน 0 หรือ 1) Unicon-Note4/3 การอินเตอรรัปต (interrupt) หรื อการขั ดจั งหวะการทํ างานของซี พี ยู นั บเป นคุ ณสมบั ติ ที่ ต องมี ในไมโครคอนโทรลเลอร สมั ยใหม และ เปนคุณสมบัติทีมี่ บทบาทสําคัญอยางมาก ในขณะทีระบบกํ ่ าลังทําการลําเลียงขวดไปตามสายพานเพือทํ ่ าการบรรจุนํายา ้ แลวเกิด เหตุการณขวดหมด จึงตองมีการขัดจังหวะกระบวนการบรรจุนํายาชั ้ วขณะ ่ จนกวาจะจัดหาขวดเขามาในระบบเปนทีเรี่ ยบรอย กระบวนการทํางานก็จะดําเนินตอไป จากตัวอยางดังกลาว ถาเปรียบเทียบกับโปรแกรมควบคุมของไมโครคอนโทรลเลอร ระบบลําเลียงขวดเพือบรรจุ ่ นํายา ้ เปรียบไดกับโปรแกรมหลัก เหตุการณขวดหมดคือ เงือนไขของการเกิ ่ ดอินเตอรรัปตที่เปนจริง ทําใหเกิดอินเตอรรัปตขึ้น การจัดหาขวดมาเพิมเติ ่ มเปรียบไดกับซีพียูกระโดดออกจากโปรแกรมหลักไปทํางานทีโปรแกรมย ่ อยบริการอินเตอรรัปต เพือจั ่ ด หาขวด นันคื ่ อ เสร็จสินการบริ ้ การอินเตอรรัปต ซีพียูก็จะกระโดดกลับมาทํางานทีโปรแกรมหลั ่ กตอไป ระบบสายพานลําเลียง ก็จะทํางานตอไปตามปกติ


Unicon  125

   4.6.1

min(x, y)

หาคาตัวเลขที่นอยที่สุดของตัวเลขสองตัว พารามิเตอร x - ตัวเลขตัวแรก เปนขอมูลประเภทใดก็ได ่ เปนขอมูลประเภทใดก็ได y - ตัวเลขตัวทีสอง คาทีส่ งกลับจากฟงกชั่น คาทีน่ อยที่สุดของตัวเลขสองตัวทีให ่ ตัวอยางที่ 4-15 sensVal = min(sensVal, 100); // assigns sensVal to the smaller of sensVal or 100, // ensuring that it never gets above 100.

ตัวอยางนี้จะไดคาของ sensVal ทีไม ่ เกิน 100 กลับจากฟงกชัน่

4.6.2

max(x, y)

หาคาตัวเลขที่มากที่สุดของตัวเลขสองตัว พารามิเตอร x - ตัวเลขตัวแรก เปนขอมูลประเภทใดก็ได ่ เปนขอมูลประเภทใดก็ได y - ตัวเลขตัวทีสอง คาทีส่ งกลับจากฟงกชั่น คาทีมากที ่ สุ่ ดของตัวเลขสองตัวทีให ่ ตัวอยางที่ 4-16 sensVal = max(senVal, 20); // assigns sensVal to the bigger of sensVal // or 20 (effectively ensuring that it is at least 20)

จากตัวอยางนี้ คาของ sensVal จะมีคาอยางนอย 20

4.6.3

abs(x)

หาคาสัมบูรณ (absolute) ของตัวเลข เปนการทําใหคาของตัวแปรเปนคาจํานวนเต็มบวก พารามิเตอร x - ตัวเลข คาทีส่ งกลับจากฟงกชั่น x เมื่อ x มีคามากกวาหรือเทากับศูนย (x มีคาเปนบวกหรือศูนย) -x เมื่อ x มีคานอยกวาศูนย (x มีคาติดลบ)


126 

4.6.4

Unicon constrain(x, a, b)

ปดคาตัวเลขที่นอยกวาหรือมากกวาใหอยูในชวงที่กําหนด พารามิเตอร x - ตัวเลขทีต ่ องการปดคาใหอยูในช  วงที่กําหนด สามารถเปนขอมูลชนิดใดก็ได a - คาตํ่าสุดของชวงทีกํ ่ าหนด b - คาสูงสุดของชวงทีกํ ่ าหนด คาทีส่ งกลับจากฟงกชั่น  าง a และ b x เมื่อ x มีคาอยูระหว a เมื่อ x มีคานอยกวา a b เมื่อ x มีคามากกวา b ตัวอยางที่ 4-17 sensVal = constrain(sensVal, 10, 150); // limits range of sensor values to between 10 and 150

จากตัวอยางนี้ คาของ sensVal จะอยูในช  วง 10 ถึง 150

   4.7.1

randomSeed(seed)

ใชกําหนดตัวแปรสําหรับสรางตัวเลขสุม โดยสามารถใชตัวแปรไดหลากหลายรูปแบบ โดยทั่วไปจะ ใชคาเวลาป จจุบัน (จากฟงกชั่น milis()) แตสามารถใชคาอยางอื่นได เชน คาที่ไดเมื่อผูใชกดสวิตช หรือคา สัญญาณรบกวนที่อานไดจากขาอินพุตอะนาลอก พารามิเตอร seed เปนคาตัวเลขแบบ long int ตัวอยางที่ 4-18 long randNumber; void setup() { Serial.begin(19200); } void loop() { randomSeed(analogRead(0)); randNumber = random(300); Serial.println(randNumber); }

ในตัวอยางนี้ กําหนดใหเกิดการสุมตัวเลขขึ้นเมื่ออานคาจากอินพุตอะนาลอกชอง 0 (A0) ยานของ ตัวเลขสุมคือ 0 ถึง 300 เมื่อทําการสุมตัวเลขแลว ใหแสดงคานันที ้ ่หนาตาง Serial Monitor


Unicon  127

4.7.2

long random(max), long random (min,max)

ใชสรางตัวเลขสุมเสมื  อน (pseudo-random numbers) เพือนํ ่ าไปใชในโปรแกรม กอนใชฟงกชันนี ้ จะต ้ อง เรียกใชฟงกชั่น randomSeed() กอน พารามิเตอร min กําหนดคาตัวเลขสุมไมนอยกวาคานี้ (เปนออปชันเพิ ่ ่มเติม) max กําหนดคาสูงสุดของตัวเลขสุม คาทีส่ งกลับจากฟงกชั่น คืนคาเปนตัวเลขสุมในชวงที่กําหนด (เปนตัวแปร long int) ตัวอยางที่ 4-21 long randNumber; void setup() { Serial.begin(19200); } void loop() { randomSeed(analogRead(2));

// return a random number from 50 - 300

randNumber = random(50,300); Serial.println(randNumber); }

ในตัวอยางนี้ กําหนดใหสุมตัวเลขเมื่ออานคาจากอินพุตอะนาลอกชอง 2 (A2) ยานของตัวเลขสุมคือ 50 ถึง 300 เมื่อทําการสุมตัวเลขแลว ใหแสดงคานันที ้ ่หนาตาง Serial Monitor


128 

Unicon


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.