IPST-MicroBOX with Wiring 1.0 (Chapter 0-4)

Page 1

   1

       1. ทําไมจึงควรใชซอฟตแวร Wiring 1.0 ขอดีของการใชซอฟตแวรพัฒนาโปรแกรมภาษา C/C++ แบบโอเพนซอรสที่ชือ่ Wiring ซึ่ง นํามาใชในชุดกลองสมองกล IPST-MicroBOX Secondary Education (SE) สําหรับหองเรียนวิทยา ศาสตรในระดับมัธยมศึกษาตอนตนตามแนวคิด สสวท. และ สอวน. ดวย มีดังนี้ รองรับกับระบบปฏิบัติการของคอมพิวเตอรทีหลากหลาย ่ ไมวาจะเปนวินโดวส (ทัง้ XP, 7 และ 8), ลีนุกซ และ MAC OSX 

ในการดาวนโหลด (อัปโหลด) โปรแกรมไปยังแผงวงจรหลักกระทําผานพอรตอนุกรมของ คอมพิวเตอรโดยตรง หรือผานทางตัวแปลงสัญญาณพอรต USB เปนพอรตอนุกรม โดยไมตองใชเครือง ่ โปรแกรมภายนอกอีก ทําใหลดขันตอนในการต ้ อพวงเครืองมื ่ อลง 

ในการพัฒนาโปรแกรมและดาวนโหลดโคดดําเนินการผานหนาตางหลักเพียงหนาตางเดียว

ไมตองสรางไฟลโปรเจ็กตหรือตังค ้ าทางฮารดแวรหรือ Configuration จึงลดขันตอนการพั ้ ฒนา โปรแกรมลงอยางมาก 

Wiring 1.0 เปนซอฟตแวรแบบซอรสเปด ใชงานไดโดยไมมีคาใชจาย และไมจํากัดเวลา รวมถึงมีการปรับปรุงอยางตอเนืองเพื ่ อให ่ ไดซอฟตแวรทีมี่ ประสิทธิภาพสูง ครู-อาจารยทีมี่ ความสนใจ ในการพัฒนาเครื่องมือสามารถนําซอรสโคดไปพัฒนาเปนซอฟตแวรที่ตอบสนองตอการเรียนการ สอนโดยเฉพาะได 

มีไลบรารีชวยในการพัฒนาโปรแกรมสําหรับติดตออุปกรณภายนอกมากมาย และใชงานงาย

ชวยลดความผิดพลาดในการแกไขบิตฟวสทีทํ่ าใหตัวไมโครคอนโทรลเลอรไมสามารถทํางาน ได เนืองจากในการใช ่ งานซอฟตแวร Wiring 1.0 ผูพั ฒนาโปรแกรมไมตองตังค ้ าพารามิเตอรใดๆ ทีเกี ่ ยว ่ ของกับไมโครคอนโทรลเลอร จึงลดโอกาสในการทีตั่ วชิปจะถูกล็อกไมใหโปรแกรมลงไดอยางมาก 


2  

2. เครื่องมือที่ตองใชในการปรับปรุงแผงวงจรหลัก 2.1 เครืองโปรแกรม ่ PX-400 หรือ PX-4000 จะใชในการโปรแกรมตัวไมโครคอนโทรลเลอร ครังแรกเพี ้ ยงครังเดี ้ ยว หลังจากปรับปรุงแลว การดาวนโหลดโคดจากคอมพิวเตอรจะกระทําผานพอร ตอนุกรมของคอมพิวเตอรโดยตรง หรือผานทางตัวแปลงสัญญาณพอรต USB เปนพอรตอนุกรม ไมตองใชเครื่องโปรแกรม PX-400 หรือ PX-4000 อีกตอไป 2.2 สายตอพอรตอนุกรม CX-4 ซึ่งมีในชุด IPST-MicroBOX อยูแลว (หากใชเครื่องโปรแกรม PX-4000 ไมตองใชสายตอตัวนี้) 2.3 ตัวแปลงสัญญาณพอรต USB เปนพอรตอนุกรม RS-232 รุน UCON-232S ซึงมี ่ ในชุด IPSTMicroBOX อยูแลว (หากใชเครื่องโปรแกรม PX-4000 ไมตองใชตัวแปลงนี้ในการปรับปรุงตัวชิป) 2.4 แผงวงจรหลัก IPST-MicroBOX 2.5 อะแดปเตอรไฟตรงในยาน +9V ถึง +12V 500mA ซึ่งมีในชุด IPST-MicroBOX อยูแลว

3. ขั้นตอนการปรับปรุงแผงวงจรหลัก IPST-MicroBOX 3.1 ติดตังโปรแกรมซอฟต ้ แวรและไดรเวอร 3.1.1 ระบบปฏิบัติการทีรองรั ่ บ ซอฟตแวรสําหรับพัฒนาโปรแกรมในโครงการ Wiring นีคื้ อ Wiring Development Environment หรือบางครังเรี ้ ยกวา Wiring IDE ทํางานไดกับระบบปฏิบัติการหรือแพล็ตฟอรม (platform) ดังนี้ 

Mac OS X 10.4 (ทั้งรุนที่ใชซีพีพียูเพาเวอรพีซีและอินเทล)

วินโดวส XP, วินโดวสวิสตา, วินโดวส 7 และ 8

Linux ทั้ง Fedora Core และ Debian (รวมถึง Ubuntu ดวย)

แพล็ตฟอรมอื่นๆ ที่สนับสนุนการทํางานของ Java 1.4 ขึ้นไป

3.1.2 ดาวนโหลดและติดตั้งโปรแกรม (3.1.2.1) ดาวนโหลดซอฟตแวร Wiring 1.0 IPST-SE จากเว็บไซต www.ipst-microbox.com โดยมีไฟลติดตังชื ้ อ่ Wiring1000_IPST_SE_130411.exe (เลขเวอรชันจะเปลียนแปลงตามการปรั ่ บปรุง ลาสุด) หากผูใช  งานมีการติดตังซอฟต ้ แวร Wiring 1.0 IPST-SE อยูก อนแลว ขอใหถอนการติตดังออก ้ แลวติดตังเวอร ้ ชันใหมนีลงไปแทน ้ การติดตังใหม ้ นี้ไมสงผลกระทบตอไฟลตัวอยางทีเคยมี ่ เก็บไวใน โฟลเดอร Wiring และเวอรชันใหมนี้ใชงานไดกับ IPST-MicroBOX [SE] และ IPST-MicroBOX เดิม


   3

(3.1.2.2) ติดตังซอฟต ้ แวร Wiring 1.0 โดยดับเบิลคลิกไฟล Wiring1000_IPST_SE_130411.exe จากนั้นคลิ กตอบตกลงในแตละขั้นตอนของการติดตั้งเหมือนกับการติดตั้งแอปพลิเคชั่นอื่นๆ ของวินโดวส จนเสร็จสิ้น (3.1.2.4) หลังจากนั้นหนาตางติดตังไดรเวอร ้ USB สําหรับติดตอกับแผงวงจรหลักของ IPSTMicroBOX ปรากฏขึ้น ใหคลิกปุม Install เพื่อเริ่มการติดตังไดรเวอร ้

(3.1.2.5) ทดสอบเปดโปรแกรมโดยเลือกทีเมนู ่ Start > All Programs > Wiring > Wiring1.0 SE จากนั้นครูหนึ่งหนาตางของซอฟตแวร Wiring 1.0 จะปรากฏขึ้น

จากนี้ซอฟตแวร Wiring 1.0 พรอมสําหรับการพัฒนาโปรแกรมแลว


4  

ตั วแปลงสัญญาณ UCON-232S

แผงวงจรหลักทีติ่ ดตั้ ง Display-io หรือ Display-Motor

แผงวงจรหลักทีติ่ ดตั้ง Display-io หรือ Display-Motor

สายสัญญาณ CX-4

เครืองโปรแกรม ่ PX-400

เครืองโปรแกรม ่ PX-400

รูปที่ 1 การเชื่อมตออุปกรณเพือปรั ่ บปรุงแผงวงจรหลัก IPST-MicroBOX (ก) กรณีใชเครืองโปรแกรม ่ PX-400 ตองตอผานตัวแปลง UCON-232S และจายไฟดวยอะแดปเตอร (ข) กรณีใชเครืองโปรแกรม ่ PX-4000 และตองจายไฟดวยอะแดปเตอรเชนกัน

3.2 เชื่อมตออุปกรณ (3.2.1) เชือมต ่ ออุปกรณดังรูปที่ 1 โดยตองเสียบแผงวงจร Display-io หรือ Display-Motor ลง บนแผงวงจรหลักของ IPST-MicroBOX (3.2.2) คลิกที่ Start > All Programs > Wiring 1.0 IPST-SE > IPST-MicroBOX > IPST plusplus Upgrade Utility เพือรั ่ นโปรแกรม IPST ++ Upgrade Utility จะปรากฏหนาตางของโปรแกรมตามรูป


   5

(3.2.3) จายไฟใหกับบอรด IPST-MicroBOX (3.2.4) ตรวจสอบพอรต USB serial port ที่เกิดจากตัวแปลง UCON-232S หรือจากเครื่อง โปรแกรม PX-4000 ควรมีตําแหนงไมเกิน COM4 ถาเกินตองทําการแกไขใหไมเกิน COM4 (ดูราย ละเอียดการเปลี่ยนตําแหนงพอรต USB serial port จากคูมือของ IPST-MicroBOX เลมที่ 1) (3.2.5) ตรวจสอบไฟแสดงสถานะ READY ของเครื่องโปรแกรม PX-400 ตองติดสวาง สวน กรณีใชเครื่องโปรแกรมรุน PX-4000 สังเกตไฟแสดงผลตองเปนสีเขียว (3.2.6) คลิกปุม Re-Detect IPST-MicroBOX เพือกํ ่ าหนดใหเกิดการเชือมต ่ อระหวางโปรแกรม IPST ++ Upgrade Utility กับเครื่องโปรแกรมและแผงวงจรหลัก IPST-MicroBOX หากการเชือมต ่ อ ถูกตองที่หนาตางหลักของโปรแกรมจะมีปุม Upgrade to IPST-PlusPlus สีสมเกิดขึ้น

(3.2.7) คลิกปุม Upgrade to IPST-PlusPlus แลวรอสักครู ซอฟตแวรจะทําการปรับปรุงเฟรมแวร ของชิปไมโครคอนโทรลเลอร ATmega16 บนแผงวงจรหลักของ IPST-MicroBOX ในขันตอนนี ้ อาจใช ้ เวลาประมาณ 1 ถึง 2 นาที ในระหวางนีไฟแสดงสถานะของเครื ้ องโปรแกรมจะเป ่ นสีแดง


6  

(3.2.8) เมื่อการโปรแกรมโคดเพื่อปรับปรุงเฟรมแวรเสร็จสิ้น ไฟแสดงสถานะของเครื่ อง โปรแกรมจะกลับมาเปนสีเขียว ที่จอ LCD แสดงขอความ IPST++ upgrade completed..

และที่หนาตางของโปรแกรมแสดงขอความแจงการอัปเกรดหรือปรับปรุงเฟรมแวร เสร็จสมบูรณ เปนอันเสร็จสิ้นการปรับปรุงแผงวงจรหลัก

หลังจากนีแผงวงจรหลั ้ กของ IPST-MicroBOX ทีติ่ ดตังแผงวงจร ้ Display-io หรือ Display-Motor จะถูกเรียกชือทางฮาร ่ ดแวรใหมสําหรับซอฟตแวร Wiring 1.0 IPST-SE วา IPST++ หรือ IPST plusplus


   7

4. การเชื่อมตอกับคอมพิวเตอรหลังจากปรับปรุงแผงวงจรแลว หลังจากปรับปรุงแผงวงจรหลักของ IPST-MicroBOX แลว จะกําหนดเปนชือใหม ่ วา IPST++ จะตองเชื่อมตอกับคอมพิวเตอรผานพอรตอนุกรม (COM) ดวยสาย CX-4 เพี่อใชในการอัปโหลด โปรแกรมและสื่อสารขอมูลกับซอฟตแวร Wiring 1.0 IPST-SE ดังนั้นจึงตองติดตังแผงวงจร ้ Displayio หรือ Display-Motor เสมอ หากคอมพิวเตอรที่ใชงานมีเฉพาะพอรต USB จะตองใชตัวแปลงสัญญาณ USB เปน RS-232 ซึงในชุ ่ ดกลองสมองกล IPST-MIcroBOX ไดเตรียมไวใหแลว นั่นคือแผงวงจร UCON-232S โดยเสียบ UCON-232S เขากับพอรต USB ของคอมพิวเตอร แลวตอสาย CX-4 เขาที่ UCON-232S สวนปลายอีก ดานของสาย CX-4 ตอเขาที่จุดตอแจกโมดูลารบนแผงวงจร Display-io หรือ Display-Motor

สิ่งที่ตองเตรียมเพิ่มอีกหนึ่งอยางคือ แหลงจายไฟ แนะนําใหใชอะแดปเตอรที่มากับชุด IPSTMicroBOX หรือใชแบตเตอรี่ AA 5 กอน (สูงสุดถึง 8 กอน) บรรจุลงในกะบะถาน AA แบบ 5 กอนที่ มากับชุด IPST-BOT หลังจากปรับปรุงฮารดแวรเปน IPST++ แลว เครื่องโปรแกรม PX-400 และ PX-4000 ก็จะไม ตองใชอี กตอไป นอกจากต องการลบหรื อปรั บปรุงเฟร มแวรในตัวชิปไมโครคอนโทรลเลอร ATmega16 ใหมอีกครัง้ หรือเมือต ่ องการกลับไปพัฒนาโปรแกรมดวย AVR Studio และใช AVR Prog ในการโปรแกรมหนวยความจําภายในตัวไมโครคอนโทรลเลอรดวยกระบวนการเดิม


8  

5. การทดสอบ (5.1) เปดซอฟตแวร Wiring 1.0 IPST-SE (5.2) เชื่อมตอ IPST++ เขากับคอมพิวเตอร (5.3) พิมพโปรแกรมทดสอบดังนี้ แลวบันทึกชือไฟล ่ เปน ipstTest.pde #include <ipst.h>

// include file for IPST-SE

void setup() { lcd("Welcome to #nWiring 1.0"); } void loop() {}

(5.4) ไปที่เมนู Tools > Board > IPST plusplus ATmega16@16MHz เพื่อเลือกฮารดแวรที่ เชื่อมตอกับซอฟตแวร Wiring 1.0

(5.5) เลือกพอรตเชือมต ่ อ โดยไปที่เมนู Tools > Serial Port > COMxx (ปกติมีคามากกวา COM3 ตรวจสอบไดที่ Control Panel > System > Device Manager > Ports) ตามตัวอยางเปน COM3


   9

(5.6) กําหนดใหแผงวงจร IPST++ เขาสูโหมดโปรแกรม  โดย (5.6.1) กดสวิตช RESET คางไว แลวกดสวิตช SW1 ตาม (5.6.2) ปลอยสวิตช RESET แลวปลอยสวิตช SW1 ทันทีที่ปลอยสวิตช SW1 แผงวงจร IPST++ จะเขาสูโหมดโปรแกรม 

ทุกครั้งที่ตองการอัปโหลดโปรแกรมลงบนแผงวงจร IPST++ จะตองกด สวิตชตามขันตอนนี ้ ้กอนเสมอ (5.7) อัปโหลดโปรแกรม (การสงโคดลงไปยังแผงวงวจรเปาหมายของซอฟตแวร Wiring 1.0 เรียกวา การอัปโหลด - upload ซึ่งตางจากซอฟตแวรอื่นๆที่มักเรียกวา การดาวนโหลด) โดยคลิกที่ปุม หรือเลือกที่เมนู File > Upload to Wiring hardware หรือกดคีย Ctrl + U


10  

(5.8) ซอฟตแวร Wiring จะทําการคอมไพล หากไมผิดพลาดจะทําการอัปโหลดโคดไปยังแผง วงจร IPST++ เมื่ออัปโหลดเสร็จสิ้นจะแสดงขอความ Done Uploading

(5.9) ที่จอ LCD ของแผงวงจร IPST++ แสดงขอความ Welcome to Wiring 1.0

หากไดตามนี้แสดงวา แผงวงจร IPST++ พรอมใชงานกับซอฟตแวร Wiring 1.0 แลว (5.10) หากการอัปโหลดลมเหลว จะแสดงหนาตางและมีขอความแจงเตือนดังนี้


   11

สาเหตุที่ 1 : แผงวงจรหลักยังอยูในโหมดรัน ทางแกไข - ตองเลือกใหแผงวงจร IPST++ เขาสูโหมดโปรแกรม  โดยกดสวิตช RESET คางไว แลวกดสวิตช SW1 คางไวตาม แลวปลอยสวิตช RESET จากนั้นจึงปลอยสวิตช SW1 สาเหตุที่ 2 : แผงวงจรหลักไมทํางานเนื่องจากไมมีไฟเลี้ยง ทางแกไข - ตอไฟเลียงให ้ แกแผงวงจรหลัก จากนันกดสวิ ้ ตช RESET และ SW1 บนแผงวงจรหลัก IPST++ เพื่อเขาสูโหมดโปรแกรม 

     เพื่อให เครื่องมือและอุปกรณอยูในสภาพที่พรอมทํางานตลอดเวลา สิ่งที่ควรกระทําทุกครั้งที่ใชงาน ชุดกลองสมองกลคือ (1) ปดสวิตช POWER ทุกครั้งที่มีการถอดหรือตอสายเขากับคอมพิวเตอรและชุดโปรแกรม (2) ปดสวิตช POWER ทุกครังที ้ ่มีการตอหรือปลดสายของแผงวงจรตรวจจับสัญญาณหรืออุปกรณใดๆ เขากับแผงวงจรหลัก (3) หลังจากทีทดลองเสร็ ่ จ ควรปดสวิตชกอนทีจะทํ ่ าการปลดสายสัญญาณเพือต ่ อแผงวงจรใหมเขาไป (4) ไมควรปลดหรือตอสายสัญญาณของแผงวงจรใดๆ เขาไปในแผงวงจรหลักในขณะกําลังทํางาน เวน แตมีขันตอนการปฏิ ้ บัติอืนใดที ่ ระบุ ่ เจาะจงวาตองสายสัญญาณในขณะทํางานของการทดลองนันๆ ้ (5) หากมีความผิดพลาดใดๆ เกิดขึน้ ตองปดสวิตชจายไฟทันที (6) ไมใชอะแดปเตอรไฟตรงที่มีแรงดันขาออกเกิน +12V กับแผงวงจหลัก (7) หลังจากเสร็จสิ้นการทดลอง ใหปลดสายเชื่อมตอคอมพิวเตอรและสายของอะแดปเตอรหรือแหลง จายไฟออกจากแผงวงจรหลักเสมอ



     13

       ในบทนีนํ้ าเสนอขอมูลในขันต ้ นของ Wiring ซึงเป ่ นเครืองมื ่ อทางซอฟตแวรสําหรับพัฒนาการ ทํางานของชุ ดกล องสมอง IPST-MicroBOX ที่ ทําการปรั บปรุ งเป น IPST++ โดยมีขั้นตอน ของกระบวนการในการพัฒนาโปรแกรมดวยซอฟตแวร Wiring สําหรับกลองสมองกล IPSTMicroBOX ทีปรั ่ บปรุงแลวดังรูปที่ 1-1 ติดตั้งซอฟตแวร - Wiring 1.0 ซอฟตแวรเขียนโปรแกรมภาษา C/C++ - ไดรเวอร USB ของแผงวงจรหลัก IPST-SE ----------------------------------------------

ตรวจสอบชองเชื่อมตอคอมพิวเตอร ของแผงวงจร IPST++ - เชื่อมตอแผงวงจร IPST++ เขากับพอรต USB - เลือกเปด Control panel > System > Hardware > Device Manager > Ports ดูที่หัวขอ USB serial port (COMx) - จําตําแหนงของ USB serial port (COMx) โดย x เปนตัวเลข ใดๆ ปกติมีคามากกวา 3 เพื่อเลือกชองติดตอสือ่ สารระหวาง คอมพิวเตอรกบั แผงวงจร IPST++

เตรียมการสรางโปรแกรมควบคุม 1. เปดซอฟตแวร Wiring 1.0 SE สรางไฟลใหม 2. เลือกชนิดของแผงวงจร ทีเ่ มนู Tools > Board > IPSTplusplus > ATmega16@16MHz 3. เลือกชองตอคอมพิวเตอร ที่เมนู Tools > Serial port > COMx โดย x เปนเลขใดๆ ไดมาจากการตรวจสอบตําแหนงที่ Device manager

เขียนโปรแกรมภาษา C/C++ แลวบันทึกไฟล คอมไพล อัปโหลดโปรแกรม โปรแกรมที่แผงวงจร IPST++ เริม่ ทํางาน

รูปที่ 1-1 แผนภาพแสดงขันตอนและกระบวนการเรี ้ ยนรูเพื  อใช ่ งานชุดกลองสมองกล IPST-MicroBOX ดวยซอฟตแวร Wiring 1.0 IPST-SE เริมจากด ่ านซาย ตั้งแตการติดตั้งโปรแกรม และการตรวจสอบ การเชือมต ่ อ ระหวางแผงวงจรควบคุมกับคอมพิวเตอร ไลมาทางขวา เริมจากขั ่ นตอนเตรี ้ ยมการสราง โปรแกรมควบคุม, เขียนโปรแกรม, คอมไพลหรือการแปลโปรแกรมภาษา C เปนภาษาเครื่อง, อัปโหลดหรือสงโปรแกรมไปยังแผงวงจร IPST++ จากนันจึ ้ งทําการรันโปรแกรมเพือตรวจสอบการทํ ่ างาน


14    

รูปที่ 1-2 หนาตางหลักของซอฟตแวร Wiring IDE ทีใช ่ ในการพัฒนาโปรแกรม

1.1 สวนประกอบของ Wiring IDE Wiring IDE ประกอบดวย 2 สวนทีสํ่ าคัญคือ เท็กซเอดิเตอร (text editor) และ ตัวแปลภาษา C (C compiler) ดานเครืองมื ่ อหรือปุมคํ  าสังที ่ ช่ วยในการพัฒนาโปรแกรมก็มีหลากหลาย สรุปดังรูปที่ 1-2

1.1.1 แถบเมนูคําสั่ง : Menu bar ประกอบดวย File, Edit, Sketch, Tools และ Help menu


     15

1.1.1.1 เมนู File

New (Ctrl+N) : สรางไฟลใหม ซึ่งในซอฟตแวร Wiring จะเรียกวา สเก็ตช (sketch) โดยจะ ถูกตั้งชื่อเปนวันที่ปจจุบันในรูปแบบ sketch_YYMMDDa เชน sketch_080407a หรือคลิกปุม บนแถบเครืองมื ่ อก็ได Open (Ctrl+O) : เลือกเปดไฟลสเก็ตช หรือคลิกปุม

บนแถบเครื่องมือก็ได

Close (Ctrl+W) : เลือกปดไฟลสเก็ตช Save (Ctrl+S) : บันทึกไฟลสเก็ตชที่เปดอยูในชือเดิ ่ ม ทํางานเหมือนกับการคลิกที่ปุม บนแถบเครื่องมือ Save as... (Ctrl+Shift+O) : บันทึกไฟลสเก็ตชที่เปดอยูในชือใหม ่ ไฟลเดิมจะไมหายไป Upload to Wiring hardware (Ctrl+U) : สงขอมูลของไฟลสเก็ตชในปจจุบันไปยังฮารดแวร Wiring I/O ปกติแลวการทํางานในลักษณะนี้มักจะเรียกวา ดาวนโหลด (donwload) แตสําหรับใน ซอฟตแวร Wiring จะเรียกกระบวนการทํางานนี้วา การอัปโหลด (upload) ทํางานเหมือนกับการคลิ กที่ปุม บนแถบเครื่องมือ Preferences : ปรับแตงการทํางานของ Wiring IDE Quit (Ctrl+Q) : ออกจากโปรแกรม Wiring และปดหนาตางของโปรแกรม Wiring ทั้งหมด


16    

1.1.1.2 เมนู Edit เปนเมนูที่บรรจุคําสังต ่ างๆ ที่ใชในการแกไขไฟลสเก็ตชที่พัฒนาบน Wiring IDE

Undo (Ctrl+Z) : ยกเลิกการกระทําคําสังก ่ อนหนานี้หรือที่พิมพลาสุด การยกเลิกคําสัง่ Undo ทําไดโดยเลือก Edit > Redo Redo (Ctrl+Y) : กลับไปทําคําสังที ่ ทํ่ ากอนหนาคําสัง่ Undo คําสังนี ่ จะใช ้ ไดก็ตอเมือได ่ ทําการ Undo ไปแลว Cut (Ctrl+X) : ลบและคัดลอกขอความที่เลือกไปเก็บที่คลิปบอรด ซึ่งทําหนาที่เปนหนวย ความจําชั่วคราวสําหรับพักขอมูล Copy (Ctrl+C) : คัดลอกขอความที่เลือกไปเก็บที่คลิปบอรด Paste (Ctrl+V) : วางขอมูลทีอยู ่ ในคลิ  ปบอรดไปยังตําแหนงทีกํ่ าหนดหรือแทนทีข่ อความทีเลื ่ อก Select All (Ctrl+A) : เลือกตัวหนังสือหรือขอความทังหมดในไฟล ้ ทีกํ่ าลังเปดอยูในเท็  กซเอดิเตอร ในขณะนัน้ Find (Ctrl+F) : คนหาขอความภายในไฟลทีเป ่ ดอยูในเท็  กซเอดิเตอร นอกจากนียั้ งคนหาและ แทนที่ดวยขอความอื่นได Find Next (Ctrl+G) : คนหาขอความหรือคําตัวถัดไปภายในไฟลที่เปดอยูในเท็กซเอดิเตอร


     17

1.1.1.3 เมนู Sketch เปนเมนูคําสังที ่ ่เกี่ยวของกับการคอมไพลไฟลสเก็ตช

Verify/Compile (Ctrl+R) : เปนคําสังคอมไพล ่ โปรแกรม ทํางานเหมือนกับการกดปุม บนแถบเครื่องมือ Import Library : ใชเลือกผนวกไฟลไลบรารีที่ตองการลงในไฟลสเก็ตช Show Sketch Folder : แสดงโฟลเดอรของไฟลสเก็ตชปจจุบัน Add File : เลือกไฟลโปรแกรมที่ตองการเพิ่มลงไปในไฟลสเก็ตช


18    

1.1.1.4 เมนู Tools เปนเมนูคําสังที ่ ่เกี่ยวของกับการเลือกใชเครื่องมือชวยในการพัฒนาโปรแกรม คําสังสํ ่ าคัญที่ ควรทราบมีดังนี้

Auto Format : เลือกใหมีการจัดรูปแบบของโคดใหดูเปนระเบียบ Serial Monitor : เลือกเปดการทํางานและแสดงผลของ Serial Monitor Board : ใชเลือกรุนของฮาร  ดแวรทีใช ่ กับ Wiring 1.0 ในทีให ่ เลือก IPST PlusPlus, ATmega16 @ 16MHz Serial Port : ใชเลือกตําแหนงของพอรตคอมพิวเตอรทีใช ่ ติดตอกับฮารดแวรจากหัวขอ Board สําหรับแผงวงจร IPST++ โดยปกติมีคาตังแต ้ COM3 ขึ้นไป

              

Wiring1.0

 

 


     19

1.1.1.5 Help

Getting Started : เปดหนาตางเกียวกั ่ บการเริมต ่ นเรียนรูและใช  งาน Wiring ของเว็บไซต http:/ /wiring.org.co/learning/tutorials/ จะตองตออินเทอรเน็ต หากตองการดูขอมูล Examples : เลือกเปดไฟลสเก็ตชของโปรแกรมตัวอยาง Reference : เปดหนาตาง Reference ของเว็บไซต Wiring ตองตออินเทอรเน็ต หากตองการดูขอมูล Find in Reference (Ctrl+Shift+F) : เลือกขอความในโคดโปรแกรมของคุณ จากนั้นเลือก Help > Find in Reference โปรแกรมจะนําขอความที่เลือกไปคนหาใน reference ถาคนหาไมพบ จะมีขอความเตือนในหนาตางหลักของโปรแกรม Wiring Hardware : เลือกดูขอมูลของฮารดแวร Wiring I/O ผานทางเครือขายอินเทอรเน็ต Troubleshooting : เปดหนาตางการแกไขปญหาในการใชงาน Wiring ของเว็บไซต Wiring Visit wiring.org.co (Ctrl+5) : เปดเว็บบราวเซอรเพื่อเยี่ยมชมโฮมเพจของ Wiring ที่ http:// wiring.org.co จะตองตออินเตอรเน็ต หากตองการดูขอมูล About Wiring : แสดงขอมูลลิขสิทธิเกี ์ ่ยวกับซอฟตแวร Wiring


20    

1.1.2 แถบเครื่องมือ : Toolbar มีฟงกชันพื ่ ้นฐาน 6 ปุม และการทํางานในขั้นตนดังนี้ Run หรือ Compile ใชในการคอมไพลโคดโปรแกรม New ใชสรางไฟลสเก็ตชใหม (ใน Wiring จะเรียกไฟลทีทํ่ าการพัฒนาวา สเก็ตช (sketch) Open เปดไฟลสเก็ตชที่มีอยู Save บันทึกไฟลสเก็ตชปจจุบันใสในโฟลเดอรของไฟลสเก็ตชที่ทํางานอยู ถาตองการ บันทึกในชืออื ่ ่น ใหเลือกใชคําสัง่ Save As จากเมนู File Upload to Wiring hardware ใชสงไฟลสเก็ตชปจจุบันไปสเก็ตชบุกและอัปโหลด โปรแกรมไปยังฮารดแวร Wiring ในทีนี่ คื้ อ แผงวงจร IPST++ (ใน Wiring จะเรียกกระบวนการดาวน โหลดโปรแกรมไปยังฮารดแวรวา อัปโหลด : upload) Serial monitor เปดการเชื่อมตอระหวางแผงวงจร IPST++ กับพื้นที่มอนิเตอรของ Wiring IDE ผานทางพอรตอนุกรมมาตรฐานและพอรตอนุกรมเสมือนที่เกิดจากไดรเวอรของวงจร แปลงสัญญาณพอรต USB เปนพอรตอนุกรมหรือ USB serial port เพื่อดูขอมูลที่สงกลับมาจากแผง วงจร IPST++ ซึ่งมีประโยชนมากในการตรวจสอบการทํางานของโปรแกรม


     21

1.1.3 Serial monitor Wiring IDE ไดผนวกเครื่องมือสําหรับแสดงผลและสงขอมูลผานพอรตอนุกรม หรือ USB เพื่อติดตอกับแผงวงจร IPST++ นันคื ่ อ Serial monitor โดยในการเขียนโปรแกรมจะตองบรรจุคําสัง่ Serial.println() ลงในโปรแกรมดวย อยางไรก็ตามกอนการใชคําสั่ง Serial.println()จะตองมีการ กําหนดคาอัตราเร็วในการถายทอดขอมูลหรืออัตราบอดหรือบอดเรต (baud rate) กอน โดยใชคําสัง่ Serial.begin()ซึ่งโดยปกติกําหนดคาเปน 9600 บิตตอวินาที และควรบรรจุคําสัง่ Serial.begin()ให อยูในสวน setup()ของโปรแกรมทุกครั้ง บนแถบเครือง ่ การเรียกใหหนาตาง Serial Monitor ใหทํางาน ทําไดงายมากเพียงคลิกทีปุ่ ม มือ หนาตาง Serial Monitor จะปรากฏขึ้นเพื่อแสดงขอความที่รับมาจากแผงวงจร IPST++ ผานทาง พอรต USB หรือพอรตอนุกรมที่ดานบนของหนาตาง Serial Monitor จะเปนชองสําหรับปอนขอมูล เพื่อสงคาจากโปรแกรมมายังแผงวงจร IPST++


22    

1.2 ขั้นตอนการพัฒนาโปรแกรม (1.2.1) ตรวจสอบการติดตังฮาร ้ ดแวรและซอฟตแวรของ Wiring รวมถึงการตังค ้ าของพอรตที่ เชือมต ่ อกับฮารดแวร Wiring I/O ในทีนี่ คื้ อ แผงวงจร IPST++ ของชุดกลองสมองกล IPST-MicroBOX (1.2.2) สรางไฟลใหมดวยการคลิกทีปุ่ ม New บนแถบเครืองมื ่ อหรือเลือกจากเมนู File > New

(1.2.3) พิมพโคดโปรแกรมตอไปนี้ #include <ipst.h> // ผนวกไฟลไลบรารีหลัก "ipst.h" void setup() { lcd("Start C/C++ with #nIPST++ board"); // แสดงขอความเริมต ่ น pinMode(PB1, OUTPUT); // กําหนดใหพอรด PD7 ทํางานเปนเอาตพุต } void loop() { digitalWrite(PB1, HIGH); // สงสัญญาณลอจิก HIGH จากพอรด PB1 ทําให LED ติดสวาง delay(500); // หนวงเวลา 0.5 วินาที digitalWrite(PB1,LOW); // สงสัญญาณลอจิก LOW จากพอรด PB1 ทําให LED ดับ delay(500); // หนวงเวลา 0.5 วินาที }

โปรแกรมนี้ใชในการทดสอบการทํางานเบื้องตนของแผงวงจร IPST++ โดยกําหนดให แสดงขอความที่จอแสดงผลและขับไฟกะพริบ LED 1 ดวงที่จุดตอพอรต PB1


     23

ตอเขากับพอรตอนุกรม ของคอมพิวเตอรโดยตรง

สาย CX-4 ปรับความสวางจอแสดงผล ของโมดูล LCD

UCON-232S

ตอสาย CX-4 เขากับ UCON-232S ตัวแปลงสัญญาณพอรต USB เปนพอรตอนุกรม ในกรณีที่คอมพิวเตอรไมมีพอรตอนุกรม

ตัวตานทาน ปรับคาได KNOB DC input

PORTC

OFF

PA7

PA6

ON

IPST MicroBOX PA4

PA5

GND PC0 PC1 PC2 PC3 PC4 PC5 PC6 PC7 +5V

SCL

KNOB PA7 LCD

ตอกับพอรต USB ของคอมพิวเตอร

RS-232

SDA

PA0

ATMEGA16

PA2

PA1

+ Vin -

PA3

S t a r t M C / C ++ O w i t h

PD0

PD1

PD7

TxD

PD6

PB4

RxD

PD5

PB2 SW3

PD4

PB0

PB3

SW2

PD3

PB1

SW1 RESET

PD2

I P S T + + y b oa r d o a r d

แผงวงจร Display-io หรือ Display-Motor

แผงวงจรหลัก MicroBOX อยูดานลาง

รูปที่ 1-3การเชือมต ่ อแผงวงจร IPST++ กับคอมพิวเตอรเพือใช ่ งานกับซอฟตแวร Wiring IDE (1.2.4) ไปที่เมนู File เลือกคําสัง่ Save As บันทึกไฟลในชือ่ ipstFirstDemo ตอนนี้จะมีไฟล ipstFirstDemo.pde เกิดขึ้นในโฟลเดอรชือว ่ า ipstFirstDemo


24    

(1.2.5) ตรวจสอบการเขียนโปรแกรมดวยการคลิกที่ปุม Run ทีแถบเครื ่ ่องมือหรือเลือกคําสัง่ จากเมนู Sketch > Compile/Verify

หากมีความผิดพลาดเกิดขึ้นจากการคอมไพล จะปรากฏขอความแจงความผิดพลาด ในชองแสดงสถานะและพื้นที่แสดงขอความ ตองทําการแกไขโปรแกรม

หากการคอมไพลถูกตอง ที่ชองแสดงสถานะจะแจงแสดงขอความ Done compiling

(1.2.6) ตอสาย CX-4 เขากับพอรอนุกรมของคอมพิวเตอร หรือตอผานตัวแปลง UCON-232S หากใชงานกับพอรต USB (ดูรูปที่ 1-2 ประกอบ) จากนั้นเปดสวิตชจายไฟเลี้ยง (1.2.7) คลิกที่ปุม Upload to Wiring Hardware บนแถบเครื่องมือ ถาทุกอยางเปนปกติ เมื่อทําการอัปโหลดเสร็จ จะมีขอความแจงที่ชองแสดงสถานะวา Done uploading. RESET to start the new program. และที่พื้นที่แสดงขอความจะแจงกระบวนการและผลคอมไพล รวมถึงขนาดของ ไฟลผลลัพธที่เกิดขึ้น


     25

ถามีขอผิดพลาดเกิดขึ้นจะมีขอความแจงในพื้นที่แสดงขอความดานลางของหนาตาง โปรแกรมหลัก

ซึ่งสวนใหญแลวมักเกิดจากการเลือกพอรตอนุกรมไมถูกตอง (1.2.8) หลังจากอัปโหลดโปรแกรมแลว นําแผงวงจร ZX-LED มาตอเขาทีจุ่ ดตอ PB1 เมื่อรัน โปรแกรม แผงวงจรหลัก IPST++ จะทํางานโดยแสดงขอความ Start

C/C++

IPST++

with

board

สวน LED ของแผงวงจร ZX-LED ที่จุดตอ PB1 จะติดดับหรือกะพริบในอัตรา 0.5 วินาทีตอครั้ง ZX-LED

ปรับความสวางจอแสดงผล ของโมดูล LCD

PA4

PA5

GND PC0 PC1 PC2 PC3 PC4 PC5 PC6 PC7 +5V

SCL

KNOB PA7 LCD

RS-232

SDA

PA2

PA1

PA0

PB1

PB0

PB3

PB2

+ Vin -

PA3

S t a r t M C / C ++ O w i t h I P S T + + y b oa r d o a r d

TxD

PD0

PD1

PD7

PB4

RxD

PD6

SW3

PD5

SW2

PD4

SW1 RESET

PD3

S

S



PD2

ATMEGA16

S

+

IPST MicroBOX

+

PA6

+

DC input

OFF

ON

O

O

O

  

PA7

+ S

PORTC

+ S + S


26    

1.3 ตําแหนงการเก็บไฟลสเก็ตชของ Wiring ผูพั ฒนาโปรแกรมบันทึกไฟลสเก็ตชไวทีใดในพื ่ นที ้ จั่ ดเก็บแฟมขอมูลของคอมพิวเตอรก็ได แต เพืออํ ่ านวยความสะดวกและจดจํางาย Wiring IDE จึงกําหนดคาตังต ้ น (default) ของตําแหนงจัดเก็บ โฟลเดอรของไฟลสเก็ตชที่พัฒนาขึนไว ้ ที่ C:\Documents and Settings\Admin (หรือชื่อผูใช  ) \My Documents\Wiring สามารถตรวจสอบรวมถึงกําหนดตําแหนงใหมได โดยไปทีเมนู ่ File > Preference จะปรากฏหนาตาง Preference ขึ้นมาดังรูป หากตองการเปลียนแปลงตํ ่ าแหนงโฟลเดอรทีจั่ ด เก็บไฟลสเก็ตชทีช่ อง Sketchbook location โดยใชเมาสคลิกทีปุ่ มค  นหาทางดานขวามือ หรือจะพิมพ ตําแหนงลงไปในชอง Sketchbook location โดยตรงก็ได จากนั้นคลิกปุม OK เพื่อตอบตกลงและ ยืนยันการเปลี่ยนแปลง

สวนพารามิเตอรหรือขอกําหนดอืนๆ ่ แนะนําใหใชตามคาทีกํ่ าหนดมา ทังนี ้ เพื ้ อลดขั ่ นตอนการ ้ พัฒนาโปรแกรมและความผิดพลาดที่อาจเกิดขึ้นไดสําหรับนักพัฒนาโปรแกรมมือใหมหรือผูเริ  มต ่ น


     27

1.4 ขอกําหนดในการแกไขและบันทึกไฟลสเก็ตช ในกรณีที่ตองการแกไขไฟลสเก็ตชเดิม ตองเปดไฟลสเก็ตชนั้นๆ ขึ้นมา ทําการแกไขโคด โปรแกรม ตรวจสอบไวยกรณดวยการคอมไพล เมื่อเรียบรอยแลว มีทางเลือกในการบันทึกไฟล 2 ทางคือ 1. บันทึกในชือเดิ ่ ม ใหใชคําสัง่ Save 2. บันทึกในชือใหม ่ ดวยคําสัง่ Save As แตไมควรบันทึกทับไฟลสเก็ตชเดิมที่ไมไดถูก เปดขึ้นมา เพราะจะทําใหการเชือมโยงไฟล ่ สับสน และทําใหเกิดความผิดพลาดในการเปดใชงานครัง้ ตอไปได ถาหากมีความตองการบันทึกทับไฟลเก็ตชเดิมทีไม ่ ไดถูกเปดขึนมา ้ จะตองทําการลบโฟลเดอร ของไฟลสเก็ตชนันออกไปเสี ้ ยกอน


28    


   29

    ภาษาที่ ใช ในโปรแกรม Wiring คือภาษา C/C++ และโปรแกรมจะทํางานแบบ C++ บนฮารดแวร Wiring I/O และแผงวงจร IPST++ (ซึ่งก็เปน Wiring I/O แบบหนึ่งที่มีการดัดแปลงให ใชในชุดกลองสมอง IPST-MicroBOX เพื่อนําไปสรางโครงงานและหุนยนต  อัตโนมัติ) จุดเดนของ ซอฟตแวร Wiring และการเขียนโปรแกรมดวยภาษา C/C++ คือ ไลบรารีของ Wiring และรูปแบบ ของโปรแกรมจะงายและสามารถใชงานไดโดยไมจําเปนตองเขาใจแนวคิดขั้นสูงเชน คลาส (class), ออบเจ็กต (object) หรือพอยนเตอร (pointer) แตยังสามารถใชฟงกชันเหล ่ านั้ นไดอยู จึงชวยให โปรแกรมสั้นลงและทําความเขาใจไดงายขึ้น

2.1 ภาษา C/C++ ภาษา C/C++ จะเริ่มทํางานที่ฟงกชั่น main() ซึ่งเปนฟงกชันหลั ่ ก เปรียบเทียบรูปแบบของ โปรแกรมภาษา C และ C++ ไดดังนี้ ตัวอยางโปรแกรมในภาษา C #include <stdio.h> int main() { printf(“hello, world\n”); return 0; }

ตัวอยางโปรแกรมในภาษา C++ #include <iostream> // provides std::cout int main() { std::cout << “Hello, world!\n”; }


30  

2.2 รูปแบบโปรแกรมภาษา C/C++ ใน Wiring ใน Wiring มีฟงกชันหลั ่ ก 2 ฟงกชันคื ่ อ setup() และ loop() โดยไมตองเขียนฟงกชัน่ main() ขึน้ เองเพราะ wiring จะสรางฟงกชัน่ main() ให โดยภายในฟงกชัน่ main() ทีสร ่ างขึนจะมี ้ โครงสรางดังนี้ int main() { setup(); for(;;) { loop(); } return 0; }

// เรียกฟงกชัน่ setup() ขึนมาทํ ้ างาน // เรียกฟงกชัน่ loop() ขึนมาทํ ้ างาน

ใน Wiring ผูพั ฒนาโปรแกรมไมตองเขียนฟงกชัน่ main() แตจะทําการแกไขเฉพาะฟงกชัน่ setup() และ loop() ซึ่งจําเปนตองมี setup()และ loop() ทุกครั้งที่เขียนโปรแกรมใน wiring

2.2.1 ฟงกชันหลั ่ กของโปรแกรมภาษา C/C++ ใน wiring ในรูปที่ 2-1 แสดงไดอะแกรมการทํางานของฟงกชันหลั ่ กในโปรแกรมของ Wiring Start

ทํางานใน สวนของ setup()

ทํางานใน สวนของ loop()

รูปที่ 2-1 โฟลวชารตแสดงการทํางานของฟงกชันหลั ่ กในโปรแกรมภาษา C/C++ ของ Wiring ซึงประกอบ ่ ดวย setup() และ loop()


   31

2.2.1.1 setup() setup() คือฟงกชั่นที่จะทํางานเพียงครั้งเดียวหลังจากโปรแกรมเริ่มทํางาน จึงมักใชในการ กําหนดคาคงทีหรื ่ อประกาศตัวแปรหลักของโปรแกรม

2.2.1.2 loop() loop() คือฟงกชันที ่ ่จะทํางานวนซํ้าหลายครั้ง จะเริ่มทํางานหลังจากทํางานในฟงกชันsetup() ่ เสร็จสิ้นลง ทั้ง setup() และ loop() เปนฟงกชันที ่ ไม ่ มีการคืนคา (void) และเปนฟงกชันที ่ ่ไมมีพารามิเตอร ตัวอยางที่ 2-1 int ledPin = PB1; void setup() { pinMode(ledPin, OUTPUT); } void loop() { digitalWrite(ledPin, HIGH); delay(1000); digitalWrite(ledPin, LOW); delay(1000); }

// LED เชื่อมตอกับแผงวงจร IPST++ ที่จุดตอ PB1

// กําหนดใหทํางานเปนขาพอรตเอาตพุต

// ตังค ้ าให LED สวาง // รอเพื่อให LED สวางคางไวประมาณ1วินาที // ตังค ้ าให LED ดับ // รอเพื่อให LED ดับคางไวประมาณ1วินาที

ตัวแปรทีทํ่ าการประกาศใหใชงานเฉพาะในฟงกชัน่ setup() จะไมสามารถใชงานไดในฟงกชัน่ loop() และเชนเดียวกันตัวแปรที่ทําการประกาศในฟงกชัน่ loop() จะไมสามารถใชงานไดในฟงกชัน่ setup() หากตองการใหตัวแปรที่กําหนดใชงานไดในทั้ง 2 ฟงกชั่น ทําไดโดย ประกาศตัวแปรเปน global declaretion นั่นคือ การประกาศตัวแปรระบบ เชน การประกาศ int ledPin = 48 ที่บรรทัดแรก

2.2.2 การใชเซมิโคลอน ; คําสังของโปรแรมภาษา ่ C/C++ จะมีสัญลักษณ ; หรือเซมิโคลอน (semicolon) ตอทายทุกครั้ง ตัวอยางที่ 2-2 int y;


32  

2.2.3 การใชวงเล็บปกกา {} (เคอรลีเบรซเซส : curly braces) {} หรือวงเล็บปกกาใชเพือบอกจุ ่ ดเริมต ่ นและจุดสินสุ ้ ดของฟงกชันและสเตตเมนต ่ ซึงอาจมี ่ ได หลายบรรทัด เชน โครงสรางของ for() และ () หรืออาจใชในการใหคาเริมต ่ นแกตัวแปรอะเรย (array) ตัวอยางที่ 2-3 int[] a = { 5, 20, 25, 45, 70 };

2.2.4 การเขียนคอมเมนต (comment) หรือคําอธิบายโปรแกรม คอมเมนตคือขอความที่ไมเกี่ยวของกับโคด อาจเปนขอความที่ผูพัฒนาโปรแกรมเขียนเพื่อ ความเขาใจของตัวเอง หรือใชในการอธิบายการทํางานของโปรแกรมในแตละบรรทัดหรือแตละ ยอหนา คอมไพเลอรจะไมแปลหรือตีความใดๆ ในสวนของคอมเมนต การเขียนคอมเมนตในโปรแกรมภาษา C/C++ มี 2 แบบ คือ // comment

เปนการเขียนคอมเมนตหนึงบรรทั ่ ด

/* comment */

เปนการเขียนคอมเมนตหลายบรรทัด

2.2.5 ไดเร็กตีฟ #include ใชผนวกไฟลไลบรารีเขากับโปรแกรมในไฟลสเก็ตช ไดเร็กตีฟ #include นี้มักถูกเขียนไว บรรทัดบนสุดของโปรแกรมเสมอ รูปแบบ : #include <ชื่อlibaryทีต่ องการinclude> ตัวอยางที่ 2-4 #include <ipst_lcd.h> // เพื่อใหสามารถใชคําสังเกี ่ ่ยวกับโมดูล LCD ได

หมายเหตุ

#include เปนไดเร็กตีฟ จึงไมตองลงทายดวยเซมิโคลอนหรือ ;


   33

2.3 ขอมูลและตัวแปร 2.3.1 การประกาศตัวแปร ในการเรียกใชงานขอมูลจําเปนตองมีตัวแปรมาเก็บขอมูลนัน้ ซึงต ่ องมีการประกาศตัวแปรกอน จึงใชงานได โดยปกติมักประกาศตัวแปรไวดานบนสุดของฟงกชันหรื ่ อตอนตนของโปรแกรม ตัวแปร ทีถู่ กประกาศในฟงกชันหนึ ่ งจะไม ่ สามารถเรียกใชไดในอีกฟงกชันหนึ ่ ง่ ตัวแปรชนิดเดียวกันสามารถ ประกาศพรอมกันหลายๆ ตัวได โดยใชเครื่องหมาย , เปนตัวแยก สรุปชนิดของตัวแปรที่ใชในโปรแกรมภาษา C/C++ ใน Wiring ดังนี้ ชนิดของตัวแปร int unsigned int long unsigned long char unsigned char float double boolean byte

คําอธิบาย เก็บตัวแปรชนิดตัวเลขทีไม ่ มีจุดทศนิยม เก็บตัวแปรชนิดตัวเลขทีไม ่ มีจุดทศนิยม เก็บตัวแปรชนิดตัวเลขทีไม ่ มีจุดทศนิยม เก็บตัวแปรชนิดตัวเลขทีไม ่ มีจุดทศนิยม เก็บตัวแปรชนิดตัวอักษร เก็บตัวแปรชนิดตัวอักษร เก็บตัวแปรชนิดตัวเลขทีมี่ จุดทศนิยม เก็บตัวแปรชนิดตัวเลขทีมี่ จุดทศนิยม เก็บตัวแปรชนิด boolean หรือ จริง (true) และ เท็จ (false) เก็บตัวแปรชนิด byte

รูปแบบ : datatype var; โดยที่ datatype คือ ชนิดของตัวแปรจะขึนอยู ้ กั บชนิดของขอมูลทีตั่ วแปรนันเก็ ้ บคา เชน int, float, char var คือ ชื่อของตัวแปร ซึงมี ่ กฏในการตั้งชือตั ่ วแปรดังนี้ (1) ชื่อตัวแปรสามารถใชตัวอักษรหรือตัวเลขหรือเครื่องหมายสัญประกาศ (เครื่องหมายขีดเสน ลาง_ หรือ under scroll) ในการตั้งชือได ่ แตตองขึนต ้ นดวยตัวอักษรภาษาอังกฤษ หรือเครื่องหมายสัญประกาศเทานัน้ (2) ชือตั ่ วแปรไมสามารถเวนวรรคไดและหามมีเครืองหมายต ่ างๆ ยกเวนเครืองหมายสั ่ ญประกาศ ในชือตั ่ วแปร เชน $, %, *, @, +, - ,/, ^ เปนตน (3) ตัวอักษรพิมพใหญและพิมพเล็กมีความแตกตางกัน (case-sensitive) (4) ชือตั ่ วแปรหามเปนคําสงวน เชน begin, end, if เปนตน

ตัวอยางที่ 2-5 int x; char a,b,c;

// ประกาศตัวแปร x เปนตัวแปรชนิดตัวเลขจํานวนเต็ม // ประกาศตัวแปร a, b และ c เปนตัวแปรชนิดตัวอักษร


34  

2.3.2 การกําหนดคาใหตัวแปร การกําหนดคาใหตัวแปรทําไดโดยใชเครืองหมาย ่ = (assignment operator) ซึงจะกํ ่ าหนดคาใหตัว แปรไดก็ตอเมือชนิ ่ ดขอมูลและชนิดของตัวแปรนันเป ้ นชนิดเดียวกัน เชน ถาขอมูลเปน interger ตัวแปร ก็ควรจะเปนชนิด interger ดวย การกําหนดคาใหตัวแปรอาจทําพรอมกับการประกาศตัวแปรก็ได รูปแบบ : var = value; โดยที่ value คือ ขอมูลที่จะใหตัวแปรนันเก็ ้ บคา var คือ ชือของตั ่ วแปรที่ตองการจะใหคา

ตัวอยางที่ 2-6 int x = 10; // ประกาศตัวแปร x เปนตัวแปรชนิดตัวเลขจํานวนเต็ม มีคาเริมต ่ นเทากับ 10 x = 20; // กําหนดใหคาตัวแปร x เทากับ 20 หมายเหตุ : ในการประกาศตัวแปรควรกําหนดคาตัวแปรดวยทุกครังเพื ้ ่อปองกันความผิดพลาดของโปรแกรม

2.3.3 ชนิดของขอมูล ในภาษาC/C++มีชนิดของขอมูลอยูหลายแบบดังตอไปนี้

2.3.3.1 int คือขอมูลที่เปนตัวเลขที่ไมมีจุดทศนิยม ขนาดขอมูลที่ตัวแปรชนิด int เก็บไดคือ 32,767 ถึง 32,768 โดยจะเก็บเปนขอมูลขนาด16 บิต ตัวอยางที่ 2-7 int x = 23;

// ประกาศตัวแปร x เปนตัวแปรชนิดตัวเลขจํานวนเต็ม มีคาเริมต ่ นเทากับ 23

2.3.3.2 unsigned int คือขอมูลทีเป ่ นตัวเลขทีไม ่ มีจุดทศนิยมและไมคิดเครืองหมาย ่ ขอมูลทีตั่ วแปรชนิดนีเก็ ้ บไดคือ 0 ถึง 65,535 โดยเก็บเปนขอมูลขนาด16 บิต ตัวอยางที่ 2-8 unsigned int y = 1024; // ประกาศตัวแปร y เปนตัวแปรชนิดตัวเลขจํานวนเต็มไมคิดเครื่องหมาย มีคาเริมต ่ นเทากับ 1024


   35

2.3.3.3 long คือชนิดขอมูลที่เปนตัวเลขจํานวนเต็มขนาด 32 บิตแบบคิดเครื่องหมาย ขอมูลที่เก็บไดคือ -2,147,483,648 ถึง 2,147,483,647 ตัวอยางที่ 2-9 long x = 10;

// ประกาศตัวแปร x เปนตัวแปรชนิด long แบบคิดเครื่องหมาย มีคาเริมต ่ นเปน 10

2.3.3.4 unsigned long คือชนิดขอมูลทีเป ่ นตัวเลขจํานวนเต็ม 32 บิตแบบไมคิดเครืองหมาย ่ มีคา 0 ถึง 4,294,967,295 ตัวอยางที่ 2-10 unsigned long y = 1024; // ประกาศตัวแปร y เปนตัวแปรชนิด long แบบไมคิดเครื่องหมาย มีคาเริมต ่ นเทากับ 1024

2.3.3.5 float คือชนิดขอมูลทีเป ่ นตัวเลขทศนิยมขนาด 32 บิต แบบคิดเครืองหมาย ่ เลขทศนิยมมักใชในการ ประมาณคาของอะนาลอกและคาที่ตอเนื่อง เพราะใหคาที่มีความละเอียดและแมนยํามากกวาขอมูล แบบจํานวนเต็ม int ขอมูลที่เก็บไดคือ -3.4028235 x 10+38 ถึง +3.4028235 x 10+38 ตัวอยางที่ 2-11 float x = 2.5;

// ประกาศตัวแปร x เปนตัวแปรชนิดเลขทศนิยมแบบคิดเครืองหมาย ่ มีคาเทากับ 2.5

2.3.3.6 double 10+38

คือชนิดขอมูลทีเป ่ นตัวเลขทศนิยม 64 บิตแบบไมคิดเครืองหมาย ่ มีคา 0 ถึง 1.7976931348623157 x ตัวอยางที่ 2-12 double y = 10.75; // ประกาศตัวแปร y เปนตัวแปรชนิดทศนิยมไมคิดเครื่องหมาย มีคาเทากับ 10.75

2.3.3.7 char คือชนิดขอมูลที่เปนตัวอักษรเชน A, d, และ $ ในรูปแบบ Unicode มีขนาด 1 ไบตหรือ 8 บิต เขียนไดโดยใช ‘ หรืออัญประกาศเดี่ยวหรือซิงเกิลโคต (single quote) ครอมขอมูล ขอมูลชนิด char จะถูกเขารหัสเปนรหัสแอสกี้ (ASCII) มีคาเปนตัวเลขระหวาง -128 ถึง 127 ตัวอยางที่ 2-13 char x = ‘a’;

// ประกาศตัวแปร x เปนตัวแปรชนิดตัวอักษร มีคาเทากับรหัสแอสกีของอั ้ กษร a


36  

2.3.3.8 unsigned char คือชนิดขอมูลที่เปนตัวอักษรเชนเดียวกับ char แตคาของขอมูลจะเปนแบบไมคิดเครื่องหมาย จึงมีคาในชวง 0 ถึง 255 ตัวอยางที่ 2-14 unsigned char y = ‘b’; unsigned char z = 200;

// ใหคาตัวแปร z มีคาเริมต ่ นเปน 200

2.3.3.9 byte คือชนิดขอมูลขนาด 8 บิต เก็บคาเปนตัวเลขระหวาง 0 ถึง 255 ชนิดขอมูลแบบนี้มักนําไปใช กับตัวแปรสําหรับรับสงขอมูลจากพอรตอนุกรม (หรือ USB serial port : พอรต USB ที่ทํางานเปน พอรตอนุกรมเสมือน) และแสดงตัวอักษรในรูปแบบที่งายกวาขอมูลชนิด char ตัวอยางที่ 2-15 byte x = 128;

// ประกาศตัวแปร x ที่มีขนาด 8 บิต มีคาเริมต ่ นเทากับ 128

2.3.3.10 boolean คือ ชนิดขอมูลทีมี่ คาเปนจริงและเท็จ ปกติขอมูลชนิด boolean จะใชควบคุมคําสังที ่ ่ใชในการ ตัดสินใจการทํางานของโปรแกรม คาของขอมูลมี 2 คาคือ จริง (true) และ เท็จ (false) ตัวอยางที่ 2-16 boolean x = true; boolean y = false;


   37

2.4 อะเรย (Array) อะเรยคือชุดของขอมูล โดยขอมูลนั้นจะเปนชนิดใดก็ได แตในอะเรยชุดเดียวกัน ชนิดของ ขอมูลตองเหมือนกันทั้งชุด ขอมูลแตละคาจะถูกเรียกดวยเลขดัชนี (index) โดยขอมูลแรกสุดคือ [0] ขอมูลถัดมาคือ [1] และเรียกตอกันไป

2.4.1 การประกาศตัวแปรอะเรย การประกาศตัวแปรอะเรย (array) คลายกับการประกาศตัวแปรทัวไป ่ แตตางกันที่ array จะตอง มีเครืองหมาย ่ [ ] ตอทายชือตั ่ วแปรทุกครังเพื ้ อบอกว ่ าตัวแปรนีเป ้ นตัวแปรชนิด array เรามักจะประกาศ ตัวแปร ชนิด array ไวดานบนสุดของฟงกชันหรื ่ อตอนตนของโปรแกรมเชนเดียวกับตัวแปรทั่วไป และตัวแปรชนิด array ทีถู่ กประกาศในฟงกชันหนึ ่ งจะไม ่ สามารถเรียกใชไดในอีกฟงกชันหนึ ่ งเช ่ นกัน การกําหนดคาใหตัวแปรอาจทําพรอมกับการประกาศตัวแปรก็ได โดยขอมูลตองอยูใน { } และแยก แตละขอมูลดวยเครื่องหมาย , รูปแบบ : datatype var[element]; โดยที่ datatype คือ ชนิดขอมูลที่จะใหตัวแปรนันเก็ ้ บคา var คือ ชื่อของตัวแปร element คือจํานวนขอมูลที่เก็บในตัวแปร อาจไมระบุก็ได

ตัวอยางที่ 2-17 float data[5]; char string[]; char string1[7] = {‘h’, ‘e’, ‘l’, ‘l’, ‘o’, ‘!’, ‘\0’}; // ประกาศตัวแปรชือ่ string1 มีคาเปน hello! char string2[] = “hello there!”; // ประกาศตัวแปรชือ่ string2 มีคาเปน hello there! int numbers[] = { 90, 150, 30 }; // ประกาศตัวแปรชือ่ numbers ซึงเป ่ นตัวแปรชนิด array // โดย numbers[0] มีคาเปน 90, numbers[1] มีคาเปน 150 และ numbers[2] มีคาเปน 30

จากตัวอยางตัวแปรชนิด char สามารถกําหนดใหเปนอะรเยได โดยเรียกวา ชุดตัวอักษร (ขอความ) หรือสายอักขระหรือ string


38  

2.4.2 การอานคาจากตัวแปรชนิดอะเรย การอานคาจากตัวแปรชนิดนีต้ องทําทีละตําแหนง ยกเวนการอานคาขอมูลจากอะเรยบางชนิด เชน char สามารถอานไดหลายตําแหนงพรอมกัน ถาตัวแปอะเรยชุดหนึงมี ่ n ขอมูล ตัวแปรชุดนีจะมี ้ คาดัชนีหรือ index ตังแต ้ 0 ถึง n-1 เชน ตัวแปร numbers[3] จะมี 3 ขอมูล และมี index เปน 0 ถึง 2 หากตองการอานคาตัวแปรอะเรย ในตําแหนงที่ n จะตองแทนคาของ index ดวย n-1 โดย n คือขนาดของอะเรย รูปแบบ : var[index] โดยที่ var คือ ชือของตั ่ วแปรอะเรย index คือ ตําแหนงของตัวแปรในชุดตัวแปรอะเรยที่ตองการอานขอมูล

ตัวอยางที่ 2-18 int numbers[3] = { 90, 150, 30 }; // ประกาศตัวแปรชือ่ numbers เปนตัวแปรอะเรย 3 ชุด int x= numbers[1]; // ประกาศตัวแปร x และกําหนดใหมีคาเทากับขอมูลที่ 2 ของ // ตัวแปร numbers ซึ่งเทากับ 150 เนืองจาก ่ index คือ 1

2.4.3 การกําหนดคาใหตัวแปรอะเรย การกําหนดคาใหตัวแปรอะเรยทําไดโดยใชเครื่องหมาย = เชนเดียวกับตัวแปรทั่วไปซึ่งจะ กําหนดคาใหไดก็ตอเมือชนิ ่ ดขอมูลและชนิดของตัวแปรเปนชนิดเดียวกัน รูปแบบ : var[index] = value; โดยที่ var คือ ชือของตั ่ วแปรชนิด array index คือ ตําแหนงของตัวแปรในชุดตัวแปรชนิด array ที่ตองการเก็บขอมูล value คือ ขอมูลที่ตองการเขียนหรือเก็บคา

ตัวอยางที่ 2-19 int numbers[3]; void setup() { numbers[0] = 90; numbers[1] = 150; numbers[2] = 30; } void loop() {}

// ประกาศตัวแปรชือ่ numbers เปนตัวแปรอะเรย 3 ชุด // กําหนดใหตัวแปร numbers ชุด 0 มีคาเทากับ 90 // กําหนดใหตัวแปร numbers ชุด 1 มีคาเทากับ 150 // กําหนดใหตัวแปร numbers ชุด 2 มีคาเทากับ 30


   39

2.5 ฟงกชันในซอฟต ่ แวร Wiring ในซอฟตแวร Wiring นอกจากฟงกชันหลั ่ ก 2 ตัวคือ setup() และ loop() แลว ผูพั ฒนาโปรแกรม สามารถสรางฟงกชันเพิ ่ ่มเติมขึ้นมาเพื่อใชงานเองได โดยฟงกชันที ่ ่สรางขึนใหม ้ สามารถเรียกใชจาก ฟงกชัน่ setup() และ loop() หรือจากฟงกชันใดๆ ่ ก็ได ฟงกชันใน ่ Wiring แบงออกเปน 2 ประเภทคือ ฟงกชันที ่ ่เมื่อทํางานจบแลวมีการคืนคา และ ฟงกชันที ่ ่เมื่อทํางานจบแลวไมคืนคา (void) เชน setup() และ loop()

2.5.1 ฟงกชันแบบไม ่ คืนคา : void เปนฟงกชันที ่ ไม ่ ตองการตัวแปรมารองรับเวลาเรียกใช และจะไมมีการใชคําสัง่ return รูปแบบ : void function(parameters) { statements; } โดยที่ function คือ ชือของฟ ่ งกชัน่ ใชหลักการตังชื ้ อเหมื ่ อนกับการตังชื ้ อตั ่ วแปร parameters คือ ขอมูลทีทํ่ าการสงผานระหวางฟงกชัน่ ในบางฟงกชันอาจไม ่ มีพารามิเตอรก็ไดหรือ อาจมีหลายพารามิเตอร โดยแยกแตละพารามิเตอรดวยเครื่องหมาย , ในการประกาศฟงกชันในส ่ วนของพารามิเตอร เหมือนกับการประกาศตัวแปร ฟงกชันที ่ มี่ พารามิเตอรเวลาเรียกใชตองใสคาของพารามิเตอรใหถูกตองดวยทุกครัง้ จํานวน และตําแหนงของพารามิเตอรในตอนรับและสงตองตรงกัน statement คือ คําสังหรื ่ อฟงกชันต ่ างๆ อาจมีไดหลายคําสัง่

ตัวอยางที่ 2-20 void setup() { pinMode(17, OUTPUT); } void loop() { digitalWrite(17, HIGH); }


40  

2.5.2 คําสั่งหลักของฟงกชันแบบคื ่ นคา : return return คือ คําสังที ่ ใช ่ ในการสงขอมูลจากฟงกชันหลั ่ งจากจบการทํางาน โดยขอมูลทีส่ งกลับนัน้ ตองเปนชนิดเดียวกับฟงกชันที ่ ประกาศ ่ ถาหากประกาศฟงกชันเป ่ นชนิด void (ฟงกชันชนิ ่ ดไมคืนคา) จะไมสามารถใชคําสัง่ return ในการสงคาได นอกจากนีคํ้ าสัง่ return ยังใชในการหยุดการทํางานของ ฟงกชันเพื ่ อไม ่ ใหโปรแกรมทํางานในสวนทีเหลื ่ อแลวกลับมายังตําแหนงที่เรียกใชงานฟงกชัน่ รูปแบบ : type function(parameters) { statements; return value; } โดยที่ type คือ ชนิดของฟงกชันซึ ่ ่งดูจากชนิดขอมูลที่ทําการ return ในที่นีคื้ อ value ชนิดของฟงกชัน่ จึงเหมือนกับชนิดตัวแปร function คือ ชือของฟ ่ งกชันใช ่ หลักการตังชื ้ อเหมื ่ อนกับการตังชื ้ อตั ่ วแปร parameters คือ ขอมูลที่ทําการสงผานระหวางฟงกชัน่ statement คือ คําสังหรื ่ อฟงกชันต ่ างๆ อาจมีไดหลายคําสัง่ value คือ ขอมูลที่ฟงกชันจะทํ ่ าการคืนคาหลังจากจบการทํางาน

ตัวอยางที่ 2-21 int val = 30; //global declaretion void setup() { Serial.begin(9600); } void loop() { int t = timestwo(val); Serial.println(t); } int timestwo(int dVal) { dVal = dVal * 2; return dVal; } จากตัวอยางฟงกชัน่ timestwo เปนฟงกชันที ่ ่คืนคาเปนเลขจํานวนเต็ม มีพารามิเตอรคือ dVal ซึงเป ่ นตัว แปรชนิด int ดังนันเมื ้ อเรี ่ ยกใชฟงกชัน่ timestwo ที่ฟงกชันloop() ่ จึงมีการสงขอมูลที่เปนชนิด int มาดวย

ตัวแปรที่ทําการประกาศในฟงกชันหนึ ่ ่งจะไมสามารถใชงานไดในอีกฟงกชันหนึ ่ ่ง หากตอง การใหตัวแปรใชงานไดในทั้งสองฟงกชัน่ ทําไดโดยประกาศตัวแปรเปน global นั่นคือ การประกาศ ตัวแปรนอกฟงกชันใดๆ ่ เชน การประกาศ val ดังในตัวอยางที่ 2-21


   41

2.6 การทําซํา(Iteration) ้ การกระทําคําสังต ่ างๆ (statement) ภายในบล็อก {} ซํ้าๆ อยางมีเงื่อนไข จะเรียกวา ลูป (loop) คําสังที ่ ่ใชเพื่อการวนลูปคือ for() และ while()

2.6.1 while() while() เปนคําสังที ่ ่ใชสรางลูป การทํางานของ while() จะกระทําคําสังต ่ างๆ หรือ statement ตอเนืองไปเรื ่ อยๆ ่ และวนทําซําต ้ อเนืองจนกว ่ าจะพบการตรวจสอบเงือนไข ่ (expression) แลวเปนจริง ควรจะมีการกําหนดคาเวลาหรือจํานวนของการวนลูป มิเชนนั้นอาจทําใหโปรแกรมจะไมมีวันออก จากลูป while() รูปแบบ : while(expression) { statements; } โดยที่ expression คือ เงือนไขในการตรวจสอบว ่ าจะทําในสวนของสเตตเมนต (statement) หรือไม statement คือ คําสังหรื ่ อฟงกชันต ่ างๆ อาจมีไดหลายคําสัง่

ตัวอยางที่ 2-22 int i = 0; void setup() { while(i<5) { i++; } j=i; // j จะมีคาเปน 4 } void loop() {}

การใชลูป while() ควรระวังเรืองเงื ่ อนไข ่ เพราะอาจทําใหโปรแกรมไมมีวันออกจากลูป (break out) ดังนั้นลูป while() เหมาะสําหรับการวนลูปที่ไมรูจํ านวนรอบแนชัด


42  

2.6.2 for() for() เปนคําสังที ่ ่ใชสรางลูป โครงสรางของคําสัง่ for() มี 3 สวนคือ คาเริ่มตน (init), ตรวจ สอบ (test) และปรับปรุง (update) แตละสวนแบงแยกกันดวยเซมิโคลอน (semi-colon) ; ลูปจะทําซํา้ ตอเนื่องจนกวาผลการตรวจสอบจะออกมาเปนเท็จ ขั้นตอนการทํางานของลูป for() สรุปไดดังนี้ (1) ทํางานในสวนของคาเริ่มตน (init statement) (2) ตรวจสอบคา (test) วา เปนจริงหรือเท็จ (3) ถาเปนจริง จะทํางานตอในขั้นตอน (4) แตถาเปนเท็จจะทํางานในขั้นตอน (6) (4) ทํางานในสวนของสเตตเมนตภายในบล็อก {} (5) ทํางานในสวนของการรปรับปรุงคา (update) แลวกลับไปทํางานในขันตอน ้ (2) อีกครัง้ (6) ออกจากลูป รูปแบบ : for(init; test; update) { statements; } โดยที่ expression คือ การกระทําระหวางตัวดําเนินการ (operator) และตัวถูกดําเนินการ(operand) init คือ สเตตเมนตที่ทํางานในตอนเริมต ่ นของลูป test คือ ถาผลตรวจสอบออกมาเปนจริง จะทํางานในสวนของ statements update คือ คําสังที ่ ่ตองกระทําเมื่อวนลูปครบหนึงรอบ ่ statements คือ คําสังที ่ ่ตองกระทํา เมื่อผลการตรวจสอบออกมาเปนจริงในแตละรอบ

ตัวอยางที่ 2-23 int i; void setup() { for(i=0; i<10; i=i+1) { digitalWrite(i, HIGH); } } void loop() {}

ดังนั้นลูป loop for() จึงเหมาะสําหรับการวนทํางานที่ทราบจํานวนรอบอยางแนชัด


   43

2.6.3 break break เปนคําสั่งที่ใชจบการทํางานของลูป เชน switch(), for(), และ while() จากนั้นจะขาม ไปกระทําคําสังที ่ ่ถัดไปจากนั้น break เปนคําสังที ่ ่หยุดการทํางานของลูปตางๆ เชน for() และ while() แมวาเงือนไขของลู ่ ปจะยังเปนจริงอยูก็ตาม รูปแบบ : break; ตัวอยางที่ 2-24 int i=0; int j; void setup() { while(i<5) { i++; break; } j=i;

// j จะมีคาเปน 1

} void loop() {}

นอกจากนั้น break ยังเปนสวนหนึ่งของคําสัง่ switch() ซึ่งจะอธิบายในสวนถัดไป


44  

2.7 เงื่อนไข (Conditionals) การตัดสินใจของโปรแกรมเกิดจากการตรวจสอบเงื่อนไข ฟงกชันที ่ ่ใชในการตัดสินใจหรือ ตรวจสอบเงื่อนไขประกอบดวย switch() และ if()

2.7.1 if...else if() เปนคําสังที ่ ใช ่ ในการตรวจสอบเงือนไข ่ (expression) ถาหากวา ตรวจสอบเงือนไขแล ่ วเปนจริง จะทําคําสังต ่ างๆ (statement) ทีอยู ่ ในบล็  อก {} ของ if() หากเปนเท็จจะไมทําคําสังที ่ อยู ่ ในบล็  อก {} ของ if() ถาหากมีคําสัง่ else รวมดวย โปรแกรมจะเลือกทําคําสังต ่ างๆทีอยู ่ ในบล็  อก {} ของ else โปรแกรม ของคุณอาจมีหรือไมมีในสวนของ else ก็ได ขึนอยู ้ กั บจํานวนของเงือนไขที ่ ต่ องการตรวจสอบ รูปแบบ : if(expression) { statements; } else { statements; } โดยที่ expression คือ เงือนไขในการตรวจสอบว ่ า จะใหกระทําคําสังในส ่ วนของ statement หรือไม statement คือ คําสังหรื ่ อฟงกชันต ่ างๆ อาจมีไดหลายคําสัง่

ขอควรรู : else ตองใชรวมกับ if() เสมอ แต if() ไมจําเปนตองมี else ก็ได หากตองการตรวจสอบมากกวาหนึ่งเงื่อนไข ใหใชคําสัง่ else if() เพื่อเพิ่มเงื่อนไขอื่นๆ อาจ จะมีการใช else if() มากกวา 1 ครั้งได เมือต ่ องการใชคําสัง่ else จะตองกําหนดไวอยูท ายสุด และโปรแกรมจะทํางานในสวนของ else ก็ตอเมือตรวจสอบเงื ่ อนไขทั ่ ้งหมดแลวพบวา เปนเท็จทั้งหมด ดังนี้ รูปแบบ : if(expression) { statements; } else if(expression) { statements; } else { statements; } โดยที่ expression คือ เงือนไขในการตรวจสอบว ่ าจะกระทําคําสังในส ่ วนของ statement หรือไม statement คือ คําสังหรื ่ อฟงกชันต ่ างๆ อาจมีไดหลายคําสัง่


   45

ตัวอยางที่ 2-25 char letter = ‘b’; void setup() { Serial.begin(9600); if(letter==‘a’) { Serial.println(“Alpha”); } else if(letter==‘b’) { Serial.println(“Bravo”); } else { Serial.println(“None”); } } void loop() {}

// ตังค ้ าอัตราบอดใหกับการสือสารข ่ อมูลอนุกรมเปน 9600 // โปรแกรมจะไมทํางานในสวนนี้ // แสดงขอความ Bravo ใน Serial Monitor ทํางาน // โปรแกรมจะไมทํางานในสวนนี้

2.7.2 switch switch() เปนคําสังที ่ ่ใชในการตัดสินใจเชนเดียวกับ if() โดย switch() เหมาะสําหรับการตัดสิน ใจที่มีทางเลือก 3 ทางขึนไป ้ โดยตัดสินใจจากการตรวจสอบขอมูลในสวนเงื่อนไข (expression) วา ตรงกับขอกําหนด (label) ในกรณี (case) ใด จากนั้นจะกระโดดไปทํางานในสวนนั้นทันที แตละ case ถูกแบงออกจากกันดวยคําสัง่ break ดังนั้นเมื่อจบการทํางานใน caseนั้นๆ แลวจะออกจาก switch() ทันที ไมทํา caseอื่นๆ อีก เมื่อมีการใชคําสัง่ switch() โปรแกรมจะตรวจสอบตั้งแต case แรกจนถึง case สุดทาย หาก ขอมูลในสวนเงื่อนไขไมตรงกับคาใน case ใดๆ และถาโปรแกรมมีการกําหนดการทํางานในขั้นตน หรือ default โปรแกรมจะทํางานในสวนนั้นแทน โดยในสวนของ default จะมีหรือไมมีก็ได รูปแบบ : switch(expression) { case label: statements; break; default: statements; }

โดยที่ expression คือ ขอมูลหรือตัวแปรทีใช ่ เปนเงือนไขในการตรวจ ่ สอบวาตรงกับขอกําหนดหรือ label ในกรณีหรือ caseใด ขอมูลหรือ ตัวแปรที่ใชตองเปนขอมูลชนิด byte, char หรือ int label คือ ขอมูลทีใช ่ ในการเปรียบเทียบ ควรเปนขอมูลชนิดเดียว กับขอมูลหรือตัวแปรที่ใชเปนเงื่อนไข statement คือ คําสังหรื ่ อฟงกชันต ่ างๆ อาจมีไดหลายคําสัง่


46  

ตัวอยางทื่ 2-26 char letter = ‘b’; void setup() { Serial.begin(9600); switch(letter) { case ‘a’: case ‘A’: Serial.println(“Alpha”); break; case ‘b’: case ‘B’: Serial.println(“Bravo”); break; default: Serial.println(“None”); break; } } void loop() { }

// ตังค ้ าอัตราบอดใหกับการสือสารข ่ อมูลอนุกรมเปน 9600

// โปรแกรมจะไมทํางานในสวนนี้

// แสดงขอความ Bravo ใน Serial Monitor ทํางาน // โปรแกรมจะไมทํางานในสวนนี้

จากตัวอยาง จะเห็นไดวา คําสัง่ case สามารถตรวจสอบไดมากกวาหนึ่งคาพรอมๆ กัน ในที่นี้ คือ ‘a’ และ ‘A’ เพราะในการเขียนโปรแกรมภาษา C/C++ นั้นเปนแบบ case-sensitive คือ ใหความ สนใจในตัวพิมพใหญและตัวพิมพเล็ก


   47

2.8 ตัวดําเนินการทางคณิตศาสตร( Mathemetic Operators) ตัวดําเนิ นการทางคณิตศาสตรใชการคํานวณทางคณิตศาสตรในโปรแกรมภาษา C/C++ ของซอฟตแวร Wiring มีดังนี้ สัญลักษณ ชือ่ +

บวก (addition)

-

ลบ (minus)

%

หารเอาเศษ (modulo)

+=

บวกแลวเก็บคาไวทีตั่ วตัง(add ้ assign)

-=

ลบแลวเก็บคาไวทีตั่ วตัง(subtract ้ assign)

/

หาร (divide)

*

คูณ (multiply)

++

เพิ่มคา (increment)

--

ลดคา (decrement)

2.8.1 + บวกคา (Addition) รูปแบบ : value1 + value2

โดยที่ value1 เปนขอมูลชนิด int หรือ float value2 เปนขอมูลชนิด int หรือ float

ตัวอยางที่ 2-27 int a = 50 + 5; int b = a + 5;

// คาของ a คือ 55 // คาของ b คือ 60

2.8.2 - ลบคา (minus) รูปแบบ : value1 - value2 ตัวอยางที่ 1-28 int c = 50 - 5; int d = c - 5; int e = d - 60;

โดยที่ value1 เปนขอมูลชนิด int หรือ float value2 เปนขอมูลชนิด int หรือ float // คาของ c คือ 45 // คาของ d คือ 40 // คาของ e คือ -20


48  

2.8.3 * คูณคา (multiply) รูปแบบ : value1 * value2 โดยที่ value1 และ value2 เปนขอมูลชนิด int, float, byte หรือ char

ตัวอยางที่ 2-29

int e = 50 * 5; int f = e * 5;

// คาของ e คือ 250 // คาของ f คือ 1250

2.8.4 / หารคา (divide) รูปแบบ : value1 / value2 โดยที่ value1 เปนขอมูลชนิด int หรือ float value2 เปนขอมูลชนิด int หรือ float แตตองไมเทากับ 0

ตัวอยางที่ 2-30 int g = 50 / 5; int h = g / 5;

// คาของ g คือ 10 // คาของ h คือ 2

2.8.5 % คํานวณหาเศษของการหาร (modulus) รูปแบบ : value1 % value2 โดยที่ value1 และ value2 เปนขอมูลชนิด int

ตัวอยางที่ 2-31

int a = 20%100; int b = 75%100;

// คาของ a คือ 20 // คาของ b คือ 75

2.8.6 += บวกแลวเก็บคาไวทีตั่ วตั้ง (add assign) ลักษณะการทํางานของคําสังนี ่ คื้ อ รูปแบบ : value1 += value2;

a+=b มีคาเหมือนกับ a = a + b

โดยที่ value1 เปนขอมูลชนิด int หรือ float value2 สามารถเปนขอมูลชนิดใดก็ได แตตองเปนชนิดเดียวกับ value1

ตัวอยางที่ 2-32 int a = 50; int b = 23; a += b;

// คาของ a คือ 73


   49

2.8.7 - = ลบแลวเก็บคาไวทีตั่ วตั้ง (subtract assign) ลักษณะการทํางานของคําสังนี ่ ้คือ a - = b มีคาเหมือนกับ a = a - b รูปแบบ : value1 -= value2; โดยที่ value1 และ value2 เปนขอมูลชนิด int หรือ float

ตัวอยางที่ 2-33 int a = 50; int b = 23; a -= b; // คาของ a คือ 27

2.8.8 ++ เพิมค ่ า (increment) เปนคําสังเพิ ่ ่มคาตัวแปรขึ้นหนึ่งคา ลักษณะการทํางานคือ a++ มีคาเหมือนกับ a = a + 1 รูปแบบ : value++ โดยที่ value เปนขอมูลชนิด int

ตัวอยางที่ 2-34 int a = 0; a++; int b = a;

// คาของ a คือ 0 // คาของ b คือ 1

2.8.9 - - ลดคา (decrement) เปนคําสังลดหรื ่ อลบคาตัวแปรลงหนึ่ง มีลักษณะการทํางานคือ a - - มีคาเหมือนกับ a = a - 1 รูปแบบ : value - โดยที่ value เปนขอมูลชนิด int

ตัวอยางที่ 2-35 int a = 5; a - -; int b = a;

// คาของ a คือ 5 // คาของ b คือ 4


50  

2.9 ตัวดําเนินการเชิงเปรียบเทียบ (Relational Operators) ตัวดําเนินการเชิงเปรียบเทียบใชในการเปรียบเทียบคาในซอฟตแวร Wiring มีดังนี้ สัญลักษณ ชือ่ <

นอยกวา (less than)

>=

มากกวาหรือเทากับ (greater than or equal to)

==

เทากัน (equality)

<=

นอยกวาหรือเทากับ (less than or equal to)

>

มากกวา (greater than)

!=

ไมเทากัน (inequality)

โดยใหผลการทํางานเปน จริง (true) หรือ เท็จ (false)

2.9.1 < นอยกวา (less than) เปนคําสังเปรี ่ ยบคานอยกวา หากใช จะคืนคา เปนจริง รูปแบบ : value1 < value2 โดยที่ value1 และ value2 เปนขอมูลชนิด int หรือ float

ตัวอยางที่ 2-36 int a = 22; int b = 23; void setup() { Serial.begin(9600); // ตังค ้ าอัตราบอดใหกับการสือสารข ่ อมูลอนุกรมเปน 9600 if(a < b) { Serial.print(“variable a is less then variable b “); // แสดงขอความที่หนาตาง Serial Monitor เมื่อคาของ a นอยกวา b } } void loop() {}


   51

2.9.2 <= นอยกวาหรือเทากับ (less than or equal to) เปนคําสังเปรี ่ ยบเทียบคานอยกวาหรือเทากับระหวางคาของตัวแปรสองตัว รูปแบบ : value1 <= value2 โดยที่ value1 และ value2 เปนขอมูลชนิด int หรือ float

ตัวอยางที่ 2-37 int a = 22; int b = 23; void setup() { Serial.begin(9600); // ตังค ้ าอัตราบอดใหกับการสือสารข ่ อมูลอนุกรมเปน 9600 if(a <= b) { Serial.print(“variable a is less or equal to variable b “); // แสดงขอความที่หนาตาง Serial Monitor เมื่อคาของ a นอยกวาหรือเทากับ b } } void loop() {}

2.9.3 > มากกวา (greater than) เปนคําสังเปรี ่ ยบเทียบคามากกวาระหวางคาของตัวแปรสองตัว รูปแบบ : value1 > value2 โดยที่ value1 และ value2 เปนขอมูลชนิด int หรือ float

ตัวอยางที่ 2-38 int a = 5; int b = 13; void setup() { Serial.begin(9600); // ตังค ้ าอัตราบอดใหกับการสือสารข ่ อมูลอนุกรมเปน 9600 if(b > a) { Serial.print(“variable b is larger the variable a”); // แสดงขอความที่หนาตาง Serial Monitor เมื่อคาของ a มากกวา b } } void loop() {}


52  

2.9.4 >= มากกวาหรือเทากับ (greater than or equal to) เปนคําสังเปรี ่ ยบเทียบคานอยกวาเทากับระหวางคาของตัวแปรสองตัว รูปแบบ : value1 >= value2 โดยที่ value1 และ value2 เปนขอมูลชนิด int หรือ float

ตัวอยางที่ 2-39

int a = 23; int b = 23; void setup() { Serial.begin(9600); // ตังค ้ าอัตราบอดใหกับการสือสารข ่ อมูลอนุกรมเปน 9600 if(a >= b) { Serial.print(“variable a is greater or equal to variable b “) // แสดงขอความที่หนาตาง Serial Monitor เมือค ่ าของ a มากกวาหรือเทากับ b } } void loop() {}

2.9.5 = = เทากับ (equality) เปนคําสังเปรี ่ ยบเทียบคาเทากับระหวางคาของตัวแปรสองตัว รูปแบบ : value1 == value2 โดยที่ value1 และ value2 เปนขอมูลชนิด int, float, char, byte, boolean

ตัวอยางที่ 2-40 int a = 23; int b = 23; void setup() { Serial.begin(9600); // ตังค ้ าอัตราบอดใหกับการสือสารข ่ อมูลอนุกรมเปน 9600 if(a == b) { Serial.print(“variables a and b are equal”); // แสดงขอความที่หนาตาง Serial Monitor เมื่อคาของ a เทากับ b } } void loop() {}


   53

2.9.6 != ไมเทากัน (inequality) เปนคําสังเปรี ่ ยบเทียบคาไมเทากันของตัวแปรสองตัว รูปแบบ : value1 != value2 โดยที่ value1 และ value2 เปนขอมูลชนิด int, float, char, byte, boolean

ตัวอยางที่ 2-41 int a = 22; int b = 23; void setup() { Serial.begin(9600); // ตังค ้ าอัตราบอดใหกับการสือสารข ่ อมูลอนุกรมเปน 9600 if(a != b) { Serial.print(“variable a is not equal to variable b”); // แสดงขอความที่หนาตาง Serial Monitor เมื่อคาของ a ไมเทากับ b } } void loop() {}


54  

2.10 ตัวดําเนินการทางตรรกะ (Logical operators) ตัวดําเนินทางตรรกะใชการคํานวณทางตรรกะ เพื่อตรวจสอบคาของตัวแปรสองคา โดยตัว ดําเนินการทางตรรกะในซอฟตแวร Wiring มีดังนี้ สัญลักษณ || && !

ชือ่ การออร (logical OR) การแอนด (logical AND) การนอต (logical NOT)

2.10.1 || การออร (logical OR) ใชเปรียบเทียบคา 2 คา โดยใหผลลัพธเปนคา true เมือค ่ าของตัวแปรตัวใดตัวหนึงเป ่ นจริง ดังนี้ ตัวแปร 1 true true false false

ตัวดําเนินการ || || || ||

ตัวแปร 2 true false true false

ผลลัพธ true true true false

รูปแบบ : expression1 || expression2 โดยที่ expression คือ การกระทําระหวางตัวดําเนินการ (operators) และตัวถูกดําเนินการ(operands)

ตัวอยางที่ 2-42 boolean x = true; boolean y = false; boolean a,b,c,d; void setup() { a = x || y; b = y || x; c = x || x; d = y || y; } void loop() {}

// a ไดผลเปน true // b ไดผลเปน true // c ไดผลเปน true // d ไดผลเปน false


   55

2.10.2 && การแอนด (logical AND) ใชเปรียบเทียบคา 2 คา โดยใหผลลัพธเปนคา true เมื่อคาของตัวแปรทั้งสองเปนจริง ดังนี้ ตัวแปร 1 true true false false

ตัวดําเนินการ && && && &&

ตัวแปร 2 true false true false

ผลลัพธ true false false false

รูปแบบ : expression1 && expression2 โดยที่ expression คือ การกระทําระหวางตัวดําเนินการ (operators) และตัวถูกดําเนินการ (operands)

ตัวอยางที่ 2-43 boolean x = true; boolean y = false; boolean a,b,c,d; void setup() { a = x && y; b = y && x; c = x && x; d = y && y; } void loop() {}

// a ไดผลเปน false // b ไดผลเปน false // c ไดผลเปน true // d ไดผลเปน false

2.10.3 ! กลับคาขอมูล (NOT) ใชกลับคาของขอมูลชนิด Boolean ของตัวแปร คืนคาเปน false ถาคาของตัวแปรเปน true และ คืนคาเปน true ถาคาของตัวแปรเปน false ดังนี้ ตัวดําเนินการ ! !

ตัวแปร true false

ผลลัพธ false true

รูปแบบ : !expression โดยที่ expression คือ การกระทําระหวางตัวดําเนินการ (operators) และตัวถูกดําเนินการ(operands)


56  

ตัวอยางที่ 2-44 boolean a = true; boolean b = false; boolean c,d; void setup() { c=!a; d=!b; } void loop() {}

//c มีคาเปน false //d มีคาเปน true

2.11 ตัวดําเนินการระดับบิต (Bitwise operators) ตัวดําเนินการระดับบิตใชในการคํานวณขอมูลระดับบิต โดยตองแปลงคาใหอยูในรู  ปของเลข ฐานสองกอน แลวเริ่มคํานวณทีละบิตที่ตรงกันของสองขอมูล สัญลักษณ | |= & &= ^ ~ << >>

ชือ่ การออรระดับบิต (bitwise OR) การออรระดับบิตแลวเก็บไวทีตั่ วตัง(bitwise ้ OR and assign) การแอนดระดับบิต (bitwise AND) การแอนดระดับบิตแลวเก็บไวทีตั่ วตัง้ (bitwise AND and assign) การเอ็กคลูซีฟ-ออรระดับบิต (bitwise XOR) กลับบิต (bitwise one’s complement) เลื่อนบิตไปทางซาย (bitwise bit shift left) เลื่อนบิตไปทางขวา (bitwise bit shift right)


   57

2.11.1 | การออรระดับบิต (bitwise OR) เปนคําสังเปรี ่ ยบเทียบบิตขอมูล 2 คา (expression) โดยคืนคาเปน “0” ถาบิตที่เปรียบเทียบทั้ง สองมีคาเปน “0” ทั้งคู นอกนั้นจะคืนคาเปน “1” มีรูปแบบการประมวลผลดังนี้ ตัวแปร 1 1 1 0 0

ตัวดําเนินการ | | | |

ตัวแปร 2 1 0 1 0

ผลลัพธ 1 1 1 0

รูปแบบ : expression1 | expression2 โดยที่ expression คือ การกระทําระหวางตัวดําเนินการ (operators) และตัวถูกดําเนินการ (operands) หรืออาจเปนขอมูล

ตัวอยางที่ 2-45 unsigned int a = 60; unsigned int b = 13; unsigned int c = 0; c = a | b;

// a มีคาเปน 60 ซึงเท ่ ากับ 0011 1100 ฐานสอง // b มีคาเปน 13 ซึ่งเทากับ 0000 1101 ฐานสอง // c มีคาเปน 61 ซึงเท ่ ากับ 0011 1101 ฐานสอง

2.11.2 |= การออรระดับบิตแลวเก็บคาไวทีตั่ วตั้ง (bitwise OR and assign) เปนการออรบิต 2 บิตแลวนําผลการออรนั้นกลับไปเก็บไวที่ตัวแปรทางซายมือหรือตัวตั้ง รูปแบบ : expression1 |= expression2; โดยที่ expression คือ การกระทําระหวางตัวดําเนินการ (operators) และตัวถูกดําเนินการ (operands) หรืออาจเปนขอมูล

ตัวอยาง 2-46 unsigned int a = 60; unsigned int b = 13; a |= b;

// a มีคาเปน 60 ซึ่งเทากับ 0011 1100 ฐานสอง // b มีคาเปน 13 ซึ่งเทากับ 0000 1101 ฐานสอง // a มีคาเปน 61 ซึ่งเทากับ 0011 1101 ฐานสอง


58  

2.11.3 & การแอนดระดับบิต (bitwise AND) เปนคําสังที ่ ใช ่ ในการเปรียบเทียบบิตขอมูล 2 คา (expression) โดยคืนคาเปน “1” ถาบิตทีเปรี ่ ยบ เทียบทั้งสองมีคาเปน “1” ทั้งคู นอกนั้นจะคืนคาเปน “0” มีรูปแบบการประมวลผลดังนี้ ตัวแปร 1 1 1 0 0

ตัวดําเนินการ & & & &

ตัวแปร 2 1 0 1 0

ผลลัพธ 1 0 0 0

รูปแบบ : expression1 & expression2 โดยที่ expression คือ การกระทําระหวางตัวดําเนินการ (operators) และตัวถูกดําเนินการ (operands) หรืออาจเปนขอมูล

ตัวอยางที่ 2-47 unsigned int a = 60; unsigned int b = 13; unsigned int c = 0; c = a & b;

// a มีคาเปน 60 ซึ่งเทากับ 0011 1100 ฐานสอง // b มีคาเปน 13 ซึ่งเทากับ 0000 1101 ฐานสอง // c มีคาเปน 12 ซึงเท ่ ากับ 0000 1100 ฐานสอง

2.11.4 &= การแอนดระดับบิตแลวเก็บคาไวทีตั่ วตั้ง (bitwise AND and assign) เปนการออรบิต 2 บิตแลวนําผลการออรนั้นกลับไปเก็บไวที่ตัวแปรทางซายมือหรือตัวตั้ง ดังนั้น a&=b จึงมีคาเหมือนกับ a=a&b รูปแบบ : expression1 &= expression2; โดยที่ expression คือ การกระทําระหวางตัวดําเนินการ (operators) และตัวถูกดําเนินการ (operands) หรืออาจเปนขอมูล

ตัวอยางที่ 2-48 unsigned int a = 60; unsigned int b = 13; a &= b;

// a มีคาเปน 60 ซึงเท ่ ากับ 0011 1100 ฐานสอง // b มีคาเปน 13 ซึงเท ่ ากับ 0000 1101 ฐานสอง // a มีคาเปน 12 ซึงเท ่ ากับ 0000 1100 ฐานสอง


   59

2.11.5 ^ การเอ็กคลูซีฟ-ออรระดับบิต (bitwise XOR) เปนคําสังที ่ ใช ่ ในการเปรียบเทียบบิตขอมูล 2 คา (expression) โดยคืนคาเปน “1” ถาบิตทีเปรี ่ ยบ เทียบทังสองมี ้ คาตางกันจะคืนคาเปน “1” แตถาหากบิตที่เปรียบเทียบมีคาเหมือนกันจะคืนคาเปน “0” มีรูปแบบการประมวลผลดังนี้ ตัวแปร 1 1 1 0 0

ตัวดําเนินการ ^ ^ ^ ^

ตัวแปร 2 1 0 1 0

ผลลัพธ 0 1 1 0

รูปแบบ : expression1 ^ expression2 โดยที่ expression คือ การกระทําระหวางตัวดําเนินการ (operators) และตัวถูกดําเนินการ (operands) หรืออาจเปนขอมูล

ตัวอยางที่ 2-49 unsigned int a = 60; unsigned int b = 13; unsigned int c = 0; c = a ^ b;

// a มีคาเปน 60 ซึงเท ่ ากับ 0011 1100 ฐานสอง // มีคาเปน 13 ซึงเท ่ ากับ 0000 1101 ฐานสอง // c มีคาเปน 49 ซึงเท ่ ากับ 0011 0001 ฐานสอง

2.11.6 ~ การกลับบิต (bitwise one’s complement) เปนคําสังที ่ ่ใชในการกลับคาลอจิกของบิตจาก “0” เปน “1” หรือจากบิต “1” เปน “0” โดยจะ กลับทีละบิตของขอมูล (expression) มีรูปแบบการประมวลผลดังนี้ ตัวดําเนินการ ~ ~

ตัวแปร 1 0

ผลลัพธ 0 1

รูปแบบ : ~ expression โดยที่ expression คือ การกระทําระหวางตัวดําเนินการ (operators) และตัวถูกดําเนินการ (operands) หรืออาจเปนขอมูล

ตัวอยางที่ 2-50 unsigned int value=4; value = ~ value;

// value มีคาเปน 4 ซึงเท ่ ากับ 0000 0100 ฐานสอง // value มีคาเปน 251ซึงเท ่ ากับ 1111 1011 ฐานสอง


60  

2.11.7 << และ <<= การเลื่อนบิตไปทางซาย เปนคําสั่งทีใช ่ ในการเลือนบิ ่ ตของขอมูลของตัวแปรหรือ expression1 ไปทางซายทีละบิตตาม จํานวนครั้ง ซึ่งกําหนดโดยคาตัวแปรหรือ expression 2 ที่อยูทางขวามือ และเพิ่มคา 0 ใหกับบิตทาง ขวาสุดหรือบิต LSB (Least Significat Bit) ในทุกครั้งที่เลื่อนบิตไปทางซาย รูปแบบ : expression1 << expression2 เลือนบิ ่ ตไปทางซายตามจํานวนที่กําหนดดวยคาของ expression2

หรือ expression1 <<= expression2; เลือนบิ ่ ตไปทางซายตามจํานวนที่กําหนดดวยคาของ expression2 แลวเก็บผลลัพธลงในตัวตังหรื ้ อตัวแปร ดานซายมือ นันคื ่ อ value <<= shift; มีการทํางานเหมือนกับ value = value << shift; โดยที่ expression คือ การกระทําระหวางตัวดําเนินการ (operators) และตัวถูกดําเนินการ (operands) หรืออาจเปนขอมูล

ตัวอยางที่ 2-51 unsigned int value=4; unsigned int shift=2; value = value << shift; value <<= shift;

// value มีคาเปน 4 ซึงเท ่ ากับ 0000 0100 ฐานสอง // value มีคาเปน 16 ซึงเท ่ ากับ 0001 0000 ฐานสอง // value มีคาเปน 64 ซึงเท ่ ากับ 0100 0000 ฐานสอง


   61

2.11.8 >> และ >>= การเลือนบิ ่ ตไปทางขวา (bitwise bit shift right) เปนคําสั่งที่ใชในการเลื่อนบิตของขอมูลของตัวแปรหรือ expression1 ไปทางขวาทีละบิตตาม จํานวนครั้ง ซึ่งกําหนดโดยคาตัวแปรหรือ expression 2 ที่อยูทางขวามือ และเพิ่มคา 0 ใหกับบิตทาง ซายสุดหรือบิต MSB (Most Significat Bit) ในทุกครั้งที่เลื่อนบิตไปทางขวา รูปแบบ : expression1 >> expression2 เลือนบิ ่ ตไปทางขาวตามจํานวนที่กําหนดดวยคาของ expression2

หรือ expression1 >>= expression2; เลือนบิ ่ ตไปทางขวาตามจํานวนที่กําหนดดวยคาของ expression2 แลวเก็บผลลัพธลงในตัวตังหรื ้ อตัวแปร ดานซายมือ นันคื ่ อ value >>= shift; มีการทํางานเหมือนกับ value = value >> shift; โดยที่ expression คือ การกระทําระหวางตัวดําเนินการ (operators) และตัวถูกดําเนินการ (operands) หรืออาจเปนขอมูล

ตัวอยางที่ 2-52 unsigned int value=4; unsigned int shift=1; value = value >> shift; value >>= shift;

// value มีคาเปน 4 ซึงเท ่ ากับ 0000 0100 ฐานสอง // value มีคาเปน 2 ซึ่งเทากับ 0000 0010 ฐานสอง // value มีคาเปน 1 ซึงเท ่ ากับ 0000 0001 ฐานสอง


62  

2.12 คาคงทีใน ่ Wiring ใน wiring มีคาคงที่ตางๆ เพื่อชวยอํานวยความสะดวกในการคํานวณทางคณิตศาสตร ซึ่งคุณ ควรทําความรูจักกอน จะเริ่มเขียนโปรแกรมดังตอไปนี้ คาคงที่

คําอธิบาย

PI

คาคงทีทางคณิ ่ ตศาสตร มีคาประมาณ 3.14159 ใชรวมกับฟงกชันใน ่ การคํานวณตรีโกณมิติ

HALF_PI

คาคงที่ทางคณิตศาสตร มีคาประมาณ 1.57079 ซึงก็ ่ คือ ครึ่งหนึงของ ่ คา PI ใชรวมกับฟงกชั่นในการคํานวณตรีโกณมิติ

TWO_PI

คาคงทีทางคณิ ่ ตศาสตร มีคาประมาณ 6.28318 ซึ่งก็คือสองเทาของ คา PI ใชรวมกับฟงกชั่นคํานวณตรีโกณมิติ

หมายเหตุ : ชือของค ่ าคงที่เหลานี้เปนคําสงวน (reserved word) นําไปตั้งเปนชื่อตัวแปรไมได

2.13 คําสังเพิ ่ มเติ ่ มใน Wiring ที่ #define ไว นอกเหนือไปจากคําสังโครงสร ่ าง (structure) หลักทีเป ่ นไปตามมาตรฐานของโปรแกรมภาษา C/C++ ใน Wiring ยังมีคําสังพิ ่ เศษเพิ่มเติมอีกหลายคําสัง่ ดังนี้

2.13.1 null ใชกําหนดเปนคาวาง หรือหมายถึง ตัวอักษร “วาง” ก็ได เขียนไดทั้ง null และ NULL ตัวอยางที่ 2-53 char str[] = “some characters”; if( str != null) { Serial.print(c); // พิมพขอความ some characters }


   63

2.13.2 false ใชกําหนดคาลอจิกเมื่อเปนเท็จ หรือเทากับ “0” ใชกับตัวแปรชนิด boolean เทานั้น ตัวอยางที่ 2-54 boolean b = false; if(b == false) { digitalWrite(17, HIGH); } else { digitalWrite(17, LOW); }

// ถาคาของ b เปนเท็จ // ทําใหขาพอรต 17 เปนลอจิก “1” ถาคาลอจิกของ b เปนเท็จ

2.13.3 true ใชกําหนดคาลอจิกเมื่อเปนจริง หรือมีคาเทากับ “1” ใชกับตัวแปรชนิด boolean เทานั้น ตัวอยางที่ 2-55 boolean b = true; if(b == true) // ถาคาของ b เปนจริง { digitalWrite(PB1, HIGH); // ทําใหจุดตอพอรต PB1 เปนลอจิก “1” ถาคาลอจิกของ b เปนจริง } else { digitalWrite(PB1, LOW); }

2.13.4 INPUT เปนคําสังกํ ่ าหนดใหขาพอรตเปนอินพุตดิจิตอล โดยเขียนคา “0” ไปยังรีจิสเตอรกําหนดทิศทาง ตัวอยางที่ 2-56 pinMode(PB2, INPUT);

// กําหนดใหจุดตอพอรต PB2 เปนอินพุตดิจิตอล

2.13.5 OUTPUT เปนคําสังกํ ่ าหนดใหขาพอรตเปนเอาตพุตดิจิตอล โดยเขียนคา “1” ไปยังรีจิสเตอรกําหนดทิศทาง ตัวอยางที่ 2-57 pinMode(17, OUTPUT);

// กําหนดใหขาพอรตหมายเลข 17 เปนเอาตพุตดิจิตอล


64  

2.13.6 LOW เปนคําสังกํ ่ าหนดคาตัวแปรเปนลอจิกตํา่ หรือเทากับ “0” ซึงมี ่ ระดับแรงดันเทากับ 0V และอาจ หมายถึงสถานะปดหรือ OFF ก็ได ตัวอยางที่ 2-58 digitalWrite(17, LOW);

// เขียนคาลอจิกตํ่าไปยังขาพอรต 17

2.13.7 HIGH เปนคําสังกํ ่ าหนดคาตัวแปรเปนลอจิกสูง หรือเทากับ “1” ซึงมี ่ ระดับแรงดัน +5V อาจหมายถึง สถานะ ON ก็ได ตัวอยางที่ 2-59 digitalWrite(17, HIGH);

// เขียนคาลอจิกสูงไปยังขาพอรต 17

2.13.8 CHANGE เปนคําสังกํ ่ าหนดใหเกิดการอินเตอรรัปตจากสัญญาณภายนอก ตัวอยางที่ 2-60 attachInterrupt(0, myFunction, CHANGE); // กําหนดใหไปทํางานที่ myfunction เมือเกิ ่ ดอินเตอรรัปตที่ขาอินพุตอินเตอรรัปตภายนอกชอง 0

2.13.9 FALLING เปนคําสังกํ ่ าหนดใหเกิดอินเตอรรัปตขึ้น เมื่อเกิดการเปลี่ยนแปลงลอจิกสูงเปนตําที ่ ขาอิ ่ นพุต อินเตอรรัปตภายนอก ตัวอยางที่ 2-61 attachInterrupt(0, myFunction, FALLING); // ไปทํางานที่ myfunction เมือเกิ ่ ดอินเตอรรัปตเนื่องจากการเปลี่ยนลอจิกจากสูงเปนตําขึ ่ น้ // ที่ขาอินพุตอินเตอรรัปตภายนอกชอง 0

2.13.10 RISING เปนคําสังกํ ่ าหนดใหเกิดการอินเตอรรัปตขึน้ เมือเกิ ่ ดการเปลียนแปลงลอจิ ่ กตํามาเป ่ นลอจิกสูง ที่ขาอินพุตอินเตอรรัปตภายนอก ตัวอยางที่ 1-62 attachInterrupt(0, myFunction, RISING); // ไปทํางานที่ myfunction เมือเกิ ่ ดอินเตอรรัปตจากการเปลียนลอจิ ่ กตํ่าเปนสูง


   65

2.13.11 LSBFIRST เปนคําสังกํ ่ าหนดลําดับของการสงหรือเลื่อนบิตขอมูล โดยกําหนดใหสงบิตนัยสําคัญตําสุ ่ ด หรือ LSB กอน มักใชรวมกับคําสัง่ shiftOut

2.13.12 MSBFIRST เปนคําสั่งกําหนดลําดับของการสงหรือเลื่อนบิตขอมูล โดยกําหนดใหสงบิตนัยสูงสุดหรือ MSB กอน มักใชรวมกับคําสัง่ shiftOut

2.14 พอยนเตอร (Pointer) หรือตัวชีข้ อมูล พอยนเตอร (pointer) คือ ขอมูลหรือตัวแปรชนิดหนึงที ่ ่เก็บคาเพือชี ่ ตํ้ าแหนงของหนวยความ จํา จะตองกําหนดชนิดของพอยนเตอรทุกครังที ้ ทํ่ าการประกาศเชนเดียวกับขอมูลทัวไป ่ ซึงชนิ ่ ดขอมูล ของพอยนเตอรตองเปนชนิดเดียวกับขอมูลที่ใชเก็บคาซึ่งใชในการชีตํ้ าแหนงของหนวยความจํา

2.14.1 การประกาศตัวแปร pointer คลายกับการประกาศตัวแปรทั่วไป ตางกันที่ชนิดของ pointer จะตองมีเครื่องหมาย * ตอทาย ทุกครั้ง เรามักจะประกาศตัวแปร pointer ไวดานบนสุดของฟงกชันหรื ่ อตอนตนของโปรแกรมเชน เดียวกับตัวแปรทัวไป ่ และตัวแปร pointer ทีถู่ กประกาศในฟงกชันหนึ ่ งจะไม ่ สามารถเรียกใชไดในอีก ฟงกชันหนึ ่ ่งเชนกัน รูปแบบ : datatype* var; โดยที่ datatype คือ ชนิดขอมูลที่เก็บคาตําแหนงของหนวยความจํา var คือ ชือของตั ่ วแปร pointer

2.14. 2 การอานคาจากตัวแปร pointer การอานคาจากตัวแปร pointer ตองทําทีละตําแหนง ยกเวนการอานคาขอมูล pointer บางชนิด เชน char สามารถใชไดหลายตําแหนงพรอมกัน รูปแบบ : var[index] โดยที่ var คือ ชื่อของตัวแปรpointer index คือ ตําแหนงของตัวแปรในชุดตัวแปร pointer ที่ตองการอานขอมูล


66  

2.14.3 การกําหนดคาให pointer การกําหนดคาใหตัวแปร pointer ทําได 2 แบบคือ การกําหนดคาแอดเดรสใหตัวแปร pointer และการกําหนดคาใหกับหนวยความจําในตําแหนงที่ pointer ชี้ (1) การกําหนดคาแอดเดรสใหตัวแปร pointer รูปแบบ : var = value; หรือ

var = &variable; โดยที่ var คือ ชือของตั ่ วแปร pointer value คือ คาแอดเดรสหรือตําแหนงของหนวยความจําที่ตองการใหตัวแปร pointer ชี้ variable คือ คาแอดเดรสของหนวยความจําของตัวแปร variable ที่ตองการใหตัวแปร pointer ชี้ เมื่อนําเครืองหมาย ่ & มาไวหนาตัวแปร จะเปนการกําหนดหรือเลือกกําหนดคาแอดเดรสของตัวแปรนัน้

(2) กําหนดคาใหกับหนวยความจําในตําแหนงที่ pointer ชี้ ทําไดโดยนําเครื่องหมาย * ไวหนาชื่อของตัวแปร pointer กอน เพื่อบอกวา คาทีจะ ่ กําหนดเปนขอมูลทีต่ องนําไปเก็บไวทีตํ่ าแหนงดังกลาว โดยใชเครื่องหมาย = เพื่อกําหนดคาเชนเดียว กับตัวแปรทัวไป ่ และจะกําหนดคาใหตัวแปรไดก็ตอเมือชนิ ่ ดขอมูลและชนิดของตัวแปร pointer เปน ชนิดเดียวกัน เชน ถาขอมูลเปน interger ตัวแปร pointer ก็ตองเปนชนิด interger ดวย รูปแบบ : *var = value; โดยที่ var คือ ชือของตั ่ วแปร pointer value คือ ขอมูลทีจะเก็ ่ บลงในแอดเดรสของหนวยความจําที่ pointer ชี้

2.15 โอเวอรโหลด (Overload) เปนความสามารถที่มีอยูใน C++ โดยการโอเวอรโหลดคือ การประกาศชื่อฟงกชั่นหลายๆ ฟงกชันเป ่ นชื่อเดียวกันได โดยมีพารามิเตอรที่แตกตางกันอาจเปนขนาดหรือชนิดของขอมูล แตทุก ฟงกชันต ่ องคืนคาเปนขอมูลชนิดเดียวกัน โดยโปรแกรมจะทราบวาเรากําลังเรียกใชฟงกชันใดได ่ จาก พารามิเตอรขณะเรียกใชงาน บางครังฟ ้ งกชันที ่ มี่ การโอเวอรโหลด อาจทําใหเกิดความผิดพลาดเนืองจากความไม ่ ชัดเจนของ ชนิดขอมูลทีเป ่ นพารามิเตอรทําใหโปรแกรมไมสามารถตัดสินใจไดวาควรเรียกใชฟงกชันใด ่


   67

2.16 โปรแกรมเชิงวัตถุ (Object-Oriented Programming : OOP) สิ่งที่ทําใหที่ภาษา C++ แตกตางจากภาษา C ก็คือ ภาษา C++ สามารถเขียนโปรแกรมเชิงวัตถุ หรือ Object-Oriented Programming (OOP) ได ดังนั้นภาษา C++ จึงมีคลาส (Class) และความสามารถ ตางๆ ของคลาส เชน การสืบทอด (Inheritance) และการแกไข (override) ซึงเป ่ นสิงสํ ่ าคัญทีทํ่ าใหภาษา C++ สามารถเขียนโปรแกรมแบบ OOP ได ดังนั้น การเขียนโปรแกรมใน Wiring จึงสามารถรองรับ การเขียนโปรแกรมในลักษณะ OOP ได ในที่นี้ขออธิบายขอมูลเบื้องตนที่ควรทราบเกี่ยวกับโปรแกรมเชิงวัตถุหรือ OOP เพื่อใชเปน ขอมูลอางอิงในขั้นตนสําหรับการเขียนโปรแกรม OOP ใน Wiring

2.16.1 คลาส (Class) คลาสในภาษา C++ คือขอบเขต (encapsulation) ที่ครอบคลุมขอมูลและฟงกชันที ่ ่ใชในการ จัดการขอมูลนัน้

2.16.1.1 ขอมูลและตัวแปรในคลาส ขอมูลทีเป ่ นสมาชิกของคลาสสามารถเปนชนิดใดก็ได และสามารถประกาศเปนพอยนเตอรได อีกดวย คลาสจะเปนเหมือนตัวแปรตัวหนึ่งหรือที่เราเรียกวา ออบเจ็กต (object)

2.16.1.2 ฟงกชันในคลาส ่ ฟงกชันที ่ ่สามารถประกาศภายในคลาสไดมี 3 ชนิดคือ 1. ฟงกชันทั ่ ่วไป 2. Constructor เปนฟงกชันที ่ ่ใชกําหนดคาเริ่มตนใหกับออบเจ็กต เปนฟงกชันพิ ่ เศษที่ จะมีชือเดี ่ ยวกับชือคลาสสามารถโอเวอร ่ โหลดไดไมจํากัดภายในคลาส ซึ่งแบงตามพารามิเตอรที่ตาง กัน Constructor จะไมมีการคืนคาใดๆ การสรางฟงกชันแบบ ่ Constructor มีขอกําหนดดังนี้ 2.1 ตองมีชือเดี ่ ยวกับคลาส 2.2 ตองไมมีการคืนคาใดๆ 2.3 constructor จะถูกเรียกขึ้นมาเปนอันดับแรกเมื่อมีการสรางออบเจ็กตของ คลาส การกําหนดคาเริ่มตนตางๆ เชน การประกาศสมาชิกในคลาสและการจองพื้นที่หนวยความจํา


68  

3. Destructor คือฟงกชันที ่ ่ใชในการทําลายออบเจ็กต เปนฟงกชันพิ ่ เศษเชนเดียวกับ Constructor ซึ่งมีชือเดี ่ ยวกับชือคลาส ่ แตจะขึ้นตนดวยเครื่องหมาย ~ โดย Destructor จะไมมีการคืน คาใดๆ และจะถูกเรียกเมื่อออบเจ็กตของคลาสนั้นๆ สิ้นสุดการทํางาน

2.16.2 ระดับการเขาถึงขอมูลและฟงกชัน่ คลาสใน C++ มีการกําหนดระดับการเขาถึงที่สําคัญอยู 3 ระดับคือ Private, Public และ Protected ดังนี้ 1. private คือ การกําหนดใหเขาถึงขอมูลไดโดยฟงกชันที ่ ่เปนสมาชิกของคลาสนั้นๆ 2. protected คือ การกําหนดใหเขาถึงขอมูลไดโดยฟงกชันที ่ เป ่ นสมาชิกของคลาสและ คลาสทีสื่ บทอดจากคลาสนั้นๆ เทานั้น 3. public คือ การกําหนดใหเขาถึงไดโดยสมาชิกอื่นๆ จากภายนอก โดยทั่วไปไมนิยม ประกาศขอมูลไวในสวนนี้

2.16.3 การประกาศคลาส เราจะเรียกใชงานขอมูลไดก็ตอเมื่อมีตัวแปรมาเก็บขอมูลและตองมีการประกาศตัวแปรเสีย กอน เรามักจะประกาศตัวแปรไวดานบนสุดของฟงกชันหรื ่ อตอนตนโปรแกรม ตัวแปรทีถู่ กประกาศ ในฟงกชันหนึ ่ งจะไม ่ สามารถเรียกใชไดในฟงกชันอื ่ น่ ตัวแปรชนิดเดียวกันสามารถประกาศพรอมกัน หลายตัวได โดยใชเครื่องหมาย , เปนตัวแยก รูปแบบ : class name{ private: statement; protected: statement; public: statement; };

// การประกาศตัวแปรและฟงกชั่นตางๆ ทีเป ่ น private // การประกาศตัวแปรและฟงกชั่นตางๆ ทีเป ่ น protected // การประกาศตัวแปรและฟงกชั่นตางๆ ทีเป ่ น public

โดยที่ name คือ ชือของคลาส ่ ซึงมี ่ กฏในการตั้งชือเช ่ นเดียวกับชือตั ่ วแปร statement คือ คําสังหรื ่ อฟงกชันต ่ างๆ อาจมีไดหลายคําสัง่


   69

ตัวอยางที่ 2-63 class Example_class { private: int x; int y; public: Example_Class() { x = 0; y = 0; } ~Example_Class() {} int Add() { return x+y; } };

// Sample Class for the C++ Tutorial // Data member // Data member // Constructor for the C++ tutorial

// Destructor for the C++ Tutorial

2.16.4 friend ขอมูลตางๆ ทีประกาศเป ่ น private ภายในคลาสจะไมสามารถเขาถึงไดจากฟงกชันที ่ ไม ่ ใชสมาชิก ของคลาสหรือคลาสภายนอก แตใน C++ มีขอยกเวนทีจะยอมให ่ ฟงกชันและคลาสภายนอกเข ่ าถึงขอมูล ทีประกาศเป ่ น private ได โดยประกาศใหฟงกชันและคลาสภายนอกนั ่ นเป ้ น friend ภายในคลาส รูปแบบ : friend class name; หรือ friend type function(parameters);


70  

2.16.5 การสืบทอด (inheritance) การสืบทอดคือการสรางคลาสใหมหรือคลาสลูก (derived class) ทีสื่ บทอดจากคลาสทีมี่ อยูแล  ว หรือจากคลาสแม (base class) โดยคลาสลูกทีสร ่ างใหมจะไดรับสืบทอดตัวแปรและฟงกชันของคลาสแม ่ มาดวย ยกเวน constructor, destructor, friend ฟงกชันและ ่ friend คลาส นอกจากนัน้ คลาสลูกยังเพิมตั ่ ว แปรและฟงกชันของตั ่ วเองได และแกไขหรือโอเวอรไรด (override) บางฟงกชันของคลาสแม ่ ไดดวย (การแกไขหรือ override เปนการแกไขฟงกชันต ่ างๆ ทีได ่ รับการสืบทอดมาจากคลาสแม โดยฟงกชันดั ่ ง กลาวจะตองมีชือและpพารามิ ่ เตอรเหมือนเดิม) การสืบทอดจะชวยลดเวลาในการเขียนโคดทีซํ่ าซ ้ อนกัน รูปแบบ : class derivedClass : public baseClass { private: statement; // การประกาศตัวแปรและฟงกชั่นตางๆ ทีเป ่ น private protected: statement; // การประกาศตัวแปรและฟงกชั่นตางๆ ทีเป ่ น protected public: statement; // การประกาศตัวแปรและฟงกชั่นตางๆ ทีเป ่ น public }; โดยที่ derivedClass คือ ชือของคลาสลู ่ กทีต่ องการสรางใหม ซึงมี ่ กฏในการตังชื ้ อเช ่ นเดียวกับชือตั ่ วแปร baseClass คือ ชือของคลาสแม ่ ที่ตองการสืบทอด statement คือ คําสังหรื ่ อฟงกชันต ่ างๆ อาจมีไดหลายคําสัง่

คลาสลูกไมสามารถเขาถึงสมาชิกของคลาสแมที่กําหนดเปน private ได แตเขาถึงสมาชิกของ คลาสแมที่กําหนดเปน protected ได


   71

    นอกจากคําสังพื ่ ้นฐานที่มีใหใชในภาษา C/C++ แลว ใน Wiring ยังมีฟงกชันและคํ ่ าสังพิ ่ เศษ เพิ่มเติมใหใชที่จะชวยใหเขียนโปรแกรมไดงายขึ้น เชน ฟงกชันในการแปลงข ่ อมูล, ฟงกชันเกี ่ ่ยวกับ ตรีโกณมิติ เปนตน

3.1 ฟงกชันในการแปลงข ่ อมูล (Conversion) ใน Wiring มีฟงกชันที ่ ใช ่ ในการแปลงขอมูลอยู ซึงสามารถเรี ่ ยกใชไดเลยโดยไมตองผนวกหรือ นําเขามาจากภายนอก โดยมีรายละเอียดดังนี้

3.1.1 boolean() ใชในการแปลงขอมูล (value) ใหเปนชนิด boolean รูปแบบ : boolean(value); โดยที่ value คือ ขอมูลชนิด int, long, float, char, byte หรือ boolean

ตัวอยางที่ 3-1 boolean b = boolean(60); boolean a = boolean(0);

// กําหนดให b มีคาเปนจริง (true) // กําหนดให a มีคาเปนเท็จ (false)

3.1.2 byte() ใชในการแปลงขอมูล (value) ใหเปนชนิด byte รูปแบบ : byte(value); โดยที่ value คือ ขอมูลชนิด int, long, float, char, byte หรือ boolean

ตัวอยางที่ 3-2 byte b = byte(260);


72  

3.1.3 char() ใชในการแปลงขอมูลใหเปนชนิด char รูปแบบ : char(value); โดยที่ value คือ ขอมูลชนิด int, long, float, char, byte หรือ boolean

ตัวอยางที่ 3-3 char c = char(126);

3.1.4 int() ใชในการแปลงขอมูลใหเปนชนิด integer หรือตัวเลขทีไม ่ มีจุดทศนิยม รูปแบบ : int(value); โดยที่ value คือ ขอมูลชนิด int, long, float, char, byte หรือ boolean

ตัวอยางที่ 3-4 int i = int(245.456);

3.1.5 long() ใชในการแปลงขอมูลใหเปนชนิด long (ไมมีจุดทศนิยม) รูปแบบ : long(value); โดยที่ value คือ ขอมูลชนิด integer, long, float, char, byte หรือ boolean

ตัวอยางที่ 3-5 long i = long(245.456);

3.1.6 float() ใชในการแปลงขอมูลใหเปนชนิด float รูปแบบ : float(value); โดยที่ value คือ ขอมูลชนิด integer, long, float, char, byte หรือ boolean

ตัวอยางที่ 3-6 float f = float(true);


   73

3.2 ฟงกชันในการคํ ่ านวณ (Calculation) ใน Wiring มีฟงกชันที ่ ่ใชในการคํานวณ เชน การหาคามากที่สุด, การหาคานอยที่สุด เปนตน ซึงช ่ วยใหเขียนโปรแกรมไดงายขึน้ คําสังเหล ่ านีสามารถเรี ้ ยกใชไดโดยไมตองผนวกไฟลไลบรารีจาก ภายนอก โดยมีรายละเอียดดังนี้

3.2.1 min() เปนคําสังหาค ่ านอยที่สุดในชุดขอมูล ฟงกชันนี ่ จะคื ้ นคาเปนคาทีน่ อยที่สุดของชุดขอมูลที่นํา มาตรวจสอบ สามารถใชกับขอมูลชนิด int หรือ float ขึ้นอยูกับชนิดของขอมูลอินพุต รูปแบบ : min(value1, value2); หรือ

min(value1, value2, value3); โดยที่ value คือ ขอมูลหรือตัวแปรที่ตองการหาคาที่นอยที่สุดซึ่งเปนตัวเลขชนิด int หรือ float

ตัวอยางที่ 3-7 int d = min(5, 9); int e = min(-4, -12); float f = min(12.3, 230.24);

// ผลลัพธที่ไดคือ d = 5 // ผลลัพธที่ไดคือ e = -12 // ผลลัพธที่ไดคือ f = 12.3

3.2.2 max() เปนคําสังหาค ่ าที่มากทีสุ่ ดในชุดขอมูล ฟงกชันนี ่ ้จะคืนคาเปนคาทีมากที ่ สุ่ ดของชุดขอมูลทีนํ่ า มาตรวจสอบ สามารถใชกับขอมูลชนิด int หรือ float ขึ้นอยูกับชนิดของขอมูลอินพุต รูปแบบ : max(value1, value2); หรือ

max(value1, value2, value3); โดยที่ value คือ ขอมูลหรือตัวแปรที่ตองการหาคาที่มากที่สุด ซึงเป ่ นตัวเลขชนิด int หรือ float

ตัวอยางที่ 3-8 int a = max(5, 9); int b = max(-4, -12); float c = max(12.3, 230.24);

// ผลลัพธที่ไดคือ a = 9 // ผลลัพธที่ไดคือ b = -4 // ผลลัพธที่ไดคือ c = 230.24


74  

3.2.3 abs() เปนคําสั่งคํานวณหาคาสัมบูรณ (absolute) หรือปริมาณ (magnitude) ของขอมูลตัวเลข ซึ่ง ผลลัพธที่ไดมีคาเปนคาบวกเสมอ ฟงกชันนี ่ ้คืนคาเปนคาสัมบูรณ ซึ่งจะเปนขอมูลชนิด int หรือ float ขึนอยู ้ กับชนิดของขอมูลอินพุต รูปแบบ : abs(value); โดยที่ value คือ ขอมูลหรือตัวแปรที่ตองการหาคาสมบูรณซึงเป ่ นตัวเลขชนิด int หรือ float

ตัวอยางที่ 3-9 int a = abs(153); int b = abs(-15); float c = abs(12.234); float d = abs(-9.23);

// กําหนดให a มีคาเปน 153 // กําหนดให b มีคาเปน 15 // กําหนดให c มีคาเปน 12.234 // กําหนดให d มีคาเปน 9.23

3.2.4 constrain() เปนคําสังจํ ่ ากัดคาของขอมูลใหอยูในขอบเขตของคาสูงสุด (max) และคาตําสุ ่ ด (min) (1) ถาคาของขอมูล (value) มากกวาคาสูงสุด ฟงกชัน่ constrain() จะคืนคาเปนคาทีมากที ่ ่สุด (2) ถาหากคาของขอมูล (value) นอยกวาคาตําสุ ่ ด ฟงกชัน่ constrain() จะคืนคาเปนคาทีน่ อย ที่สุด (min) (3) ถาคาของขอมูล (value) อยูในชวงที่กําหนด ฟงกชัน่ constrain() จะคืนคาเปนคาเดิม ชนิดของขอมูลที่คืนอาจเปนชนิด int หรือ float ขึ้นอยูกับขอมูลอินพุต รูปแบบ : constrain (value, min, max); โดยที่ value คือ ขอมูลหรือตัวแปรที่ตองการจํากัดขอบเขต ซึงเป ่ นตัวเลขชนิด int หรือ float min คือ คาตําสุ ่ ดของขอบเขตขอมูล ซึงเป ่ นตัวเลขชนิด int หรือ float max คือ คาสูงสุดของขอบเขตขอมูล ซึงเป ่ นตัวเลขชนิด int หรือ float

ตัวอยางที่ 3-10 int data = 100; int t = constrain(data, 30, 70);

// คาของ t จะถูกเปลี่ยนเปน 70 ซึงอยู ่ ในชวง 30 ถึง 70


   75

3.2.5 round() เปนคําสังที ่ ่ใชคํานวณหาคาเลขจํานวนเต็มที่ใกลเคียงกับคาของขอมูล (value) มากที่สุด เชน round(9.1); จะไดผลลัพธเปน 9 คืนคาเปนขอมูลชนิด int เสมอ รูปแบบ : round (value); โดยที่ value คือ ขอมูลหรือตัวแปรชนิด float

ตัวอยางที่ 3-11 float x = 8.22; int rx = round(x); float y = 9.9; int ry = round(y); float z = -10.6; int rz = round(z);

// ผลลัพธที่ไดคือ rx = 8 // ผลลัพธที่ไดคือ ry = 10 // ผลลัพธที่ไดคือ rz = -11

3.2.6 floor() เปนคําสังคํ ่ านวณหาคาทีใกล ่ เคียงกับคาของขอมูล (value) มากที่สุด โดยคาทีได ่ จะตองนอย กวาหรือเทากับคาทีเป ่ นพารามิเตอร คืนคาเปนขอมูลชนิด float รูปแบบ : floor (value); โดยที่ value คือ ขอมูลหรือตัวแปรชนิด float

ตัวอยางที่ 3-12 float x = 2.88; float a = floor(x);

// ผลลัพธที่ไดคือ a = 2.0

3.2.7 ceil() เปนคําสังคํ ่ านวณหาคาทีใกล ่ เคียงกับคาของขอมูล (value) มากทีสุ่ ด โดยคาทีได ่ จะตองมากกวา หรือเทากับคาทีเป ่ นพารามิเตอร คืนคาเปนขอมูลชนิด float รูปแบบ : ceil (value); โดยที่ value คือ ขอมูลหรือตัวแปรชนิด float

ตัวอยางที่ 3-13 float x = 8.22; float a = ceil(x);

// ผลลัพธที่ไดคือ a = 9.0


76  

3.2.8 pow() เปนคําสังคํ ่ านวณหาคาเลขยกกําลัง คืนคาเปนผลลัพธของเลขยกกําลังซึงเป ่ นขอมูลชนิด float รูปแบบ : pow(base, exponent); โดยที่ base คือ เลขฐาน เปนตัวเลขชนิด int หรือ float exponent คือ เลขชีกํ้ าลัง เปนตัวเลขชนิด int หรือ float

ตัวอยางที่ 3-14 float a = pow( 1, 3); float b = pow( 3, 5); float c = pow( 3,-5); float d = pow(-3, 5);

// a มีคาเปน 13 หรือ 1*1*1 = 1 // b มีคาเปน 35หรือ 3*3*3*3*3 = 243 // c มีคาเปน 1 / 3*3*3*3*3 = 1 / 243 = .0041 // d มีคาเปน -3*-3*-3*-3*-3 = -243

3.2.9 sq() เปนคําสังคํ ่ านวณหาคาของเลขยกกําลัง 2 คืนคาผลลัพธเปนบวก และคาทีได ่ เปนขอมูลชนิด float รูปแบบ : sq(value); โดยที่ value คือ ขอมูลหรือตัวแปรชนิด int หรือ float

ตัวอยางที่ 3-15 float a = sq(1); float b = sq(-5); float c = sq(9);

// a มีคาเปน 1 มาจาก 1 x 1=1 // b มีคาเปน 25 มาจาก 5 x 5 = 25 // c มีคาเปน 81 มาจาก 9 x 9=81

3.2.10 sqrt() เปนคําสังที ่ ใช ่ ในการคํานวณหาคาของรากทีสอง ่ (square root) ของตัวเลข คืนคาเปนผลลัพธของ การถอดรากทีสองของค ่ านัน้ ฟงกชัน่ sqrt() คืนคาเปนบวกเสมอ และคาทีคื่ นจะเปนขอมูลชนิด float รูปแบบ : sqrt(value); โดยที่ value คือ ขอมูลหรือตัวแปรชนิด int หรือ float ซึงเป ่ นเลขบวกเสมอ

ตัวอยางที่ 3-16 float a = sqrt(6561); float b = sqrt(625); float c = sqrt(1);

// a มีคาเปน 81 มาจาก 81 x 81 = 6561 // b มีคาเปน 25 มาจาก 25 x 25 =625 // c มีคาเปน 1 มาจาก 1 x 1 = 1


   77

3.2.11 map() เปนคําสังแปลงค ่ าของขอมูลใหอยูในชวงที่ตองการ คาที่คืนจากฟงกชันเป ่ นขอมูลชนิด float รูปแบบ : map(value, low1, high1, low2, high2); โดยที่ value low1 high1 low2 high2

คือ ขอมูลหรือตัวแปรที่ตองการแปลงคา เปนขอมูลชนิด float คือ ขอบเขตลางเดิมของขอมูลหรือตัวแปรที่ตองการแปลงคาเปนขอมูลชนิด float คือ ขอบเขตบนเดิมของขอมูลหรือตัวแปรที่ตองการแปลงคา เปนขอมูลชนิด float คือ ขอบเขตลางใหมของขอมูลหรือตัวแปรที่ตองการแปลงคาเปนขอมูลชนิด float คือ ขอบเขตบนใหมของขอมูลหรือตัวแปรที่ตองการแปลงคา เปนขอมูลชนิดfloat

ตัวอยางที่ 3-17 int value; int m; void setup() { Serial.begin(9600); } void loop() { value = analogRead(0); m = (int)map(value, 0, 1023, 0, 255); Serial.println(m); delay(100); }

// จากเดิมคา m อยูในชวง 0 ถึง 1023 // ใชmap() เพื่อแปลงใหอยูในชวง 0 ถึง 255 // แสดงผลคาของตัวแปร m


78  

3.3 ฟงกชันตรี ่ โกณมิติ (Trigonometry) ใน Wiring มีฟงกชันที ่ ่ใชในการคํานวณคามุมและตรีโกณมิติ ดังตอไปนี้

3.3.1 sin() เปนคําสังคํ ่ านวณหาคาของไซน (sine) ของมุม โดยคาของมุมตองอยูในหนวยเรเดียน ซึ่งมีคา ระหวาง 0 ถึง 6.28 และจะคืนคาอยูในชวง -1 ถึง 1 เปนขอมูลชนิด float รูปแบบ : sin(angle); โดยที่ angle คือ มุมที่ตองการคํานวณอยูในหน  วยเรเดียน (PI ถึง -PI) และตองเปนขอมูลชนิด float

3.3.2 cos() เปนคําสังคํ ่ านวณหาคาของโคไซน (cosine) ของมุม โดยคาของมุมตองอยูในหน  วยเรเดียน ซึง่ มีคาระหวาง 0 ถึง 6.28 และจะคืนคาอยูในชวง -1 ถึง 1 เปนขอมูลชนิด float รูปแบบ : cos(angle); โดยที่ angle คือ มุมที่ตองการคํานวณอยูในหน  วยเรเดียน (PI ถึง -PI) และตองเปนขอมูลชนิด float

3.3.3 tan() เปนคําสังหาค ่ าของแทนเจนต (tangent : tan) ของมุม ซึงเป ่ นอัตราสวนของ sine และ cosine คาของ มุมอยูในหน  วยเรเดียน มีคา 0 ถึง 6.28 และจะคืนคาอยูในช  วง - infinity ถึง infinity เปนขอมูลชนิด float รูปแบบ : tan(angle); โดยที่ angle คือ มุมที่ตองการคํานวณอยูในหน  วยเรเดียน (PI ถึง -PI) และตองเปนขอมูลชนิด float

3.3.4 atan2() เปนคําสั่งคํานวณหาคามุมในหนวยเรเดียน ซึ่งวัดจากจุดพารามิเตอรเทียบกับจุดตังต ้ นหรือ origin โดยวัดจากแกน x ทางบวก ฟงกชันจะคื ่ นคาในชวง PI ถึง -PI เปนชนิด float ฟงกชัน่ atan2() นิยมใชในการหาตําแหนงของเคอรเซอร รูปแบบ : atan2(y, x); โดยที่ y คือ จุดในแกน y เปนขอมูลชนิด int หรือ float x คือ จุดในแกน x เปนขอมูลชนิด int หรือ float การกําหนดคาพารามิเตอรของคําสัง่ atan2() คาของจุดในแกน y ตองมากอนจุดในแกน x เสมอ


   79

3.3.5 degrees() เปนคําสังที ่ ่ใชในการแปลงมุมในหนวยเรเดียนใหเปนมุมในหนวยองศา (degree) โดย 2Pi เร เดียน = 360 องศา คาทีคื่ นมาเปนตัวเลชนิด float รูปแบบ : degrees(angle); โดยที่ angle คือมุมทีต่ องการคํานวณในหนวยเรเดียน (PI ถึง -PI) และตองเปนขอมูลชนิด int หรือ float

ตัวอยางที่ 3-18 void setup() { Serial.begin(9600); } void loop() { float rad = PI/4; float deg = degrees(rad); Serial.print(rad); Serial.print(“ radians is “); Serial.print(deg); Serial.println(“ degrees”); }

// ตังค ้ าอัตราบอดใหกับพอรตอนุกรมเปน 9600 บิตตอวินาที

// กําหนดคาใหตัวแปร rad เปนมุมแบบ radian มีคา PI/4 // แปลงมุมในหนวยเรเดียนใหเปนองศา Pi/4 เทากับ 45.0 องศา // แสดงคาของตัวแปร rad // แสดงคาของตัวแปร deg

3.3.6 radians() เปนคําสังแปลงมุ ่ มในหนวยองศา (degree) ใหเปนมุมในหนวยเรเดียน โดย 360 องศา = 2PI = 3.1428 เรเดียน เชน 90 องศา = PI/2 = 1.5707964 คาทีคื่ นมาเปนตัวเลขชนิด float รูปแบบ : radians(angle); โดยที่ angle คือมุมทีต่ องการคํานวณในหนวยเรเดียน (PI ถึง -PI) และตองเปนขอมูลชนิดinteger หรือ float

ตัวอยางที่ 3-19 float deg = 45.0; float rad = radians(deg);


80  

3.4 ฟงกชันสุ ่ มคา ใน Wiring มีฟงกชันที ่ ่ใชในการสุมตัวเลขหรือ Random มีรายละเอียดดังนี้

3.4.1 random() เปนคําสังสุ ่ มตัวเลข ในแตละครั้งที่เรียกใชฟงกชัน่ random() จะมีการคืนคาเปนตัวเลขชนิด float หรือตัวเลขที่มีจุดทศนิยมที่อยูในชวงที่กําหนดไว (value) หากในการเรียกใชฟงกชันกํ ่ าหนดคา ใหเพียง 1 คา โปรแกรมทําการสุมตั  วเลขในชวงตังแต ้ 0 ถึงคาทีกํ่ าหนดไว ฟงกชัน่ random() สามารถ เรียกใชได 2 รูปแบบดังนี้ รูปแบบ : random(value1); หรือ

random(value1, value2); โดยที่ value คือขอมูลชนิด int หรือ float

ตัวอยางที่ 3-20 void setup() { Serial.begin(9600); } void loop() { int val = random(-40, 40); // กําหนดให val เปนตัวแปรเก็บคาที่ไดจากการสุมในชวง -40 ถึง 40 Serial.print(“val = “); Serial.println(val); int x = random(5); // กําหนดให x เปนตัวแปรเก็บคาที่ไดจากการสุมในช  วง 0 ถึง 5 Serial.print(“x = “); Serial.println(x); }


   81

3.4.2 randomSeed() เปนคําสังกํ ่ าหนดคาเริ่มตนใหกับคําสัง่ random() เพื่อกําหนดผลที่ไดจากการสุมค  า รูปแบบ : randomSeed(value); โดยที่ value คือ ขอมูลชนิด int

ตัวอยางที่ 3-21 void setup() { Serial.begin(9600); randomSeed(20); } void loop() { int randNum = random(0, 500); Serial.println(randNum, 2); delay(500); }

// กําหนดคาเริมต ่ นใหการสุม

คําสัง่ random() จะทําการสุมคาใหผลเปนเลขชุดหนึง่ แมเมือเริ ่ มการทํ ่ างานใหมก็จะสุมได  ตัว เลขชุดเดิม ในกรณีที่คาพารามิเตอรตางๆเหมือนกัน คําสัง่ randomSeed() จะทําใหผลของการสุมเปลี  ่ยนไปแมวาคาของพารามิเตอรตางๆ ของคํา สั่ง random() จะเหมือนกัน ดังนั้นหากมีความตองการสุมค  าแบบมีความกระจายของขอมูลสูงควรใช คําสั่ง randomSeed(); เพื่อกําหนดคาเริ่มตน โดยคา value ควรนํามาจากแหลงกําเนิดขอมูลที่มีการ เปลี่ ยนแปลงตลอดเวลา เชน คาจากฐานเวลา หรือคาจากการแปลงสัญญาณอะนาลอกเปนดิจิตอล จากนั้นจึงใชคําสัง่ random() เพื่อสุมคาตอไป


82  

3.5 ฟงกชันเกี ่ ่ยวกับเวลา ใน Wiring มีฟงกชันที ่ ่ใชในกําหนดคาหนวงเวลา (delay) และคํานวณเวลา ซึ่งสามารถเรียก ใชไดโดยไมตองผนวกไฟลไลบรารีเพิ่มเติม มีรายละเอียดดังนี้

3.5.1 delay() เปนคําสังที ่ ่ทําใหเกิดการหนวงเวลาในหนวยมิลลิวินาที รูปแบบ : delay(milliseconds); โดยที่ milliseconds คือ ขอมูลหรือตัวแปรชนิด int เปนตัวกําหนดคาเวลาในหนวยมิลลิวินาที โดยที่ 1 วินาที = 1000 มิลลิวินาที

3.5.2 delayMicroseconds() เปนคําสังที ่ ่ทําใหเกิดการหนวงเวลาในหนวยไมโครวินาที รูปแบบ : delayMicroseconds(microseconds); โดยที่ microseconds คือ ขอมูลหรือตัวแปรชนิด long เปนตัวกําหนดคาเวลาในหนวย ไมโครวินาที โดยที่ 1 วินาที = 1,000,000 ไมโครวินาที

3.5.3 millis() เปนคําสังคื ่ นคาเวลาทีนั่ บไดตังแต ้ โปรแกรมเริมทํ ่ างานในหนวยมิลลิวินาที คาทีคื่ นเปนขอมูล ชนิด long รูปแบบ : millis(); ตัวอยางที่ 3-22 ตัวอยางนีแสดงการใช ้ คําสัง่ millis ในการสรางวงจรตังเวลาเพื ้ ่อควบคุมการทํางานของ LED ใหติดสวาง หลัง จากที่เวลาผานไป 7 วินาที โดยจะเริมนั ่ บเวลาเมือมี ่ การกดสวิตช int ledPin = PB1; // ตอ ZX-LED กับขาพอรต PB1 ของแผงวงจร IPST++ int switchPin = PB5; // เลือกใชสวิตช SW1 ทีต่ อกับพอรต PB5 ของแผงวงจร IPST++ long previousTime = 0; // กําหนดตัวแปรเก็บคาเวลาขณะที่กดสวิตช boolean press = false; // ตัวแปรบอกสถานะการกดสวิตช


   83

void setup() { pinMode(ledPin, OUTPUT); // กําหนดใหขาพอรต PB1 ทํางานเปนเอาตพุต pinMode(switchPin, INPUT); // กําหนดใหขาพอรต PB5 ทํางานเปนอินพุต } void loop() { if(digitalRead(switchPin) == LOW) // ตรวจสอบสวิตชวามีการกดหรือไม { previousTime = millis(); // เก็บคาเวลาจริง ณ ปจจุบันเปนจุดเริมต ่ นนับเวลา press = true; // มีการกดสวิตช } // ตรวจสอบวา หลังจากกดสวิตชเวลาผานไป 7 วินาทีแลวหรือไม if(((millis() - previousTime) >= 7000 )&&(press == true)) { previousTime = 0; // รีเซตหรือเคลียรเวลาที่ถูกเก็บไว digitalWrite(ledPin, HIGH); // ขับ LED ใหสวาง delay(1000); // หนวงเวลาให LED สวางนานประมาณ 1 วินาที digitalWrite(ledPin, LOW); // ดับ LED press = false; // รีเซตหรือเคลียรสถานะการกดสวิตช } } เมื่อทําการรันโปรแกรม LED ที่ขาพอรต PB1 จะดับ เมื่อมีการกดสวิตช SW1 และเวลาผานไป 7 วินาที LED จะติดสวาง 1 วินาที แลวดับลงอีกครัง้ โปรแกรมจะทําการตรวจสอบคาที่ขาพอรต PB5 ที่ตอกับ SW1 วาเปนลอจิกตํ่า หรือไม หากมีการกดสวิตช คาลอจิกจะเปนลอจิกตํ่า ตัวแปร press ซึงเป ่ นตัวแปรบอกสถานะการกดสวิตช มีคาเปน true จากนันตรวจสอบในขั ้ นต ้ อไปวา หลังจากกดสวิตชเวลาผานไป 7 วินาทีแลวหรือไม ถาเงือนไขนี ่ เป ้ นจริง LED ถูกขับใหสวางประมาณ 1 วินาที แตถาหากคาที่ไดจากคําสัง่ digitalRead() มีคาเปน HIGH แสดงวาไมมีการกดสวิตช ก็จะไมมีการนับเวลาเพื่อทําให LED ติดสวาง และจะวนตรวจสอบเชนนีไปตลอด ้ เนืองจากคํ ่ าสังทั ่ งหมดนั ้ นอยู ้ ในฟ  งกชัน่ loop()


84  

3.6 String ใน Wiring มี String class ที่ใชสําหรับตัวอักษรหรือ string โดยเฉพาะ ซึ่งความแตกตางระ หวาง string class และอะเรยของ char ก็คือ String class มีกระบวนการชวยในการจัดการกับขอมูล ตัวอักษรเพื่อลดความยุงยากในการเขียนโปรแกรม เชน ความสามารถในการพิจารณาแยกแตละตัว อักษร, การเปรียบเทียบ string, การคนหา string, การแยกสวนของ string, และการแปลง string ให เปนตัวพิมพเล็ก (lower case) และตัวพิมพใหญ(upper case) Wiring String class มีความแตกตางกับ String class ของ Java ตรงที่บางกกระบวนการหรือ เมธอดจะแกไขคาของ string นั้นจริงๆ ไมใชเพียงคืนคาทีเป ่ นผลจากการทําเมธอดนั้นๆ ขอมูลชนิด String จะอยูในเครื่องหมายอัญประกาศหรือเครื่องหมายคําพูด “ หรือ double quotes เสมอ เชน “Abc” และขอมูลชนิด cha จะอยูในเครื่องหมายอัญประกาศเดี่ยวหรือ ‘ (single quotes) เสมอ เชน ‘A’

3.6.1 การประกาศตัวแปร String class การประกาศตัวแปร String class คลายกับการประกาศตัวแปรทัวไป ่ มักจะประกาศตัวแปรนี้ ไวบนสุดของฟงกชันหรื ่ อตอนตนของโปรแกรม ตัวแปร String class ทีถู่ กประกาศในฟงกชันหนึ ่ งจะไม ่ สามารถเรียกใชไดในอีกฟงกชันหนึ ่ ง่ การกําหนดคาใหตัวแปรอาจทําพรอมกับการประกาศตัวแปรก็ได รูปแบบ : String var; โดยที่ var คือ ชือของตั ่ วแปร String class มีขอกําหนดเชนเดียวกันกับการประกาศตัวแปรทั่วๆไป

ตัวอยางที่ 3-23 String a = “IPST”; char data[] = {‘I’, ‘P’, ‘S’, ‘T’}; String b = String(data); void setup() { Serial.begin(9600); // ตังค ้ าอัตราบอดใหกับโมดูลสือสารข ่ อมูลผานพอรตอนุกรมเปน 9600 Serial.println(a); // สงคาของตัวอักษร IPST ออกไปยังพอรตอนุกรม Serial.println(b); // สงคาของอะเรยตัวอักษร IPST ออกไปยังพอรตอนุกรม } void loop() {}


   85

3.6.2 การกําหนดคาให String class การกําหนดคาใหตัวแปร String class ทําไดโดยใชเครืองหมาย ่ = เชนเดียวกับตัวแปรชนิด char จะกําหนดคาใหตัวแปรแบบนีได ้ ก็ตอเมือชนิ ่ ดขอมูลเปน String class เหมือนกัน หรือใชคําสัง่ String() แปลงขอมูลใหเปน string รูปแบบ : String(data) โดยที่ data คือ ขอมูลชนิด byte[], char[], int หรือ String

เนื่องจากอะเรยของตัวอักษร (char) รวมกันเปน string ได และขอมูลชนิด byte ถอดรหัสเปน ตัวอักษรได ดังนั้นอะเรยของ byte จึงรวมกันเปน string ไดเชนกัน และนําขอมูลชนิด int มาใชแทน ตัวอักษรพิเศษบางตัว ตัวอยางที่ 3-24 char t[] = “A character string”; String a = String(“hello”); String b = String(“ there”); String c = String(t); void setup() { Serial.begin(9600); a += b; Serial.println(c); Serial.println(a); } void loop() {}

// ตังค ้ าอัตราบอดเปน 9600 // ตัวแปร a ตอนนีจะเก็ ้ บขอความ ‘hello there’ // สงขอความ A character string ออกไปยังพอรตอนุกรม // สงขอความที่เก็บไวในตัวแปร a ออกไปยังพอรตอนุกรม


86  

3.6.3 เมธอดตางๆใน String class ในการเขาถึงเมธอดตางๆ ใน String class ทําไดโดยนําตัวแปร String class มา . (dot) แลวตาม ดวยฟงกชันหรื ่ อคําสังที ่ ต่ องการ สําหรับเมธอดทีตั่ วแปร String class ใน Wiring ใชไดมีดังนี้

3.6.3.1 length() เปนคําสังคื ่ นคาเปนความยาวหรือจํานวนตัวอักษรของ String รูปแบบ : string. length(); โดยที่ string คือตัวแปร String class

ตัวอยางที่ 3-25 String str1 = “IPST”; void setup() { str1 = “IP”; int l1 = str1.length(); Serial.begin(9600); // ตังค ้ าอัตราบอดใหกับโมดูลสือสารข ่ อมูลผานพอรตอนุกรมเปน 9600 Serial.println(l1, DEC); // ทีหน ่ าตาง Serial monitor แสดง 2 เทากับจํานวนอักษรของตัวแปร str1 } void loop() {}


   87

3.6.3.2 replace() เปนคําสังแทนที ่ ่ตัวอักษรใน string (char1) ดวยตัวอักษรที่กําหนดไว (char1) รูปแบบ : string.replace(char1, char2) โดยที่ char1 คือ ตัวอักษรที่ตองการคนหาเพื่อแทนที่ ตองเปนขอมูลชนิด char char2 คือ ตัวอักษรที่ตองการนําไปแทนที่ ตองเปนขอมูลชนิด char string คือตัวแปร String class

ตัวอยางที่ 3-26 String str = “WWWX”; void setup() { Serial.begin(9600); str.replace(‘W’,’1'); Serial.println(str); } void loop() {}

// ตังค ้ าอัตราบอดใหกับโมดูลสือสารข ่ อมูลผานพอรตอนุกรมเปน 9600 // แทนที่อักษร W ทุกตัวดวยเลข 1 // ที่หนาตาง Serial monitor ของ Wiring IDE จะแสดงขอความ 111X


88  

3.6.3.3 setCharAt() เปนคําสังแทนที ่ ตั่ วอักษรใน string ทีอยู ่ ในตํ  าแหนงทีกํ่ าหนดไว (index) ดวยตัวอักษรทีกํ่ าหนด ไว (ch) ซึ่งตําแหนงของ index จะไดรับการคํานวณแบบเดียวกับอะเรย กลาวคือ ถา string มีความยาว n ตัวอักษร index จะอยูในชวง 0 ถึง n-1 โดยตัวอักษรแรกสุดคือ 0 ตัวอักษรถัดไปคือ 1 รูปแบบ : string.setCharAt(index, ch); โดยที่ index คือ ตําแหนงของตัวอักษรที่ตองการแทนที่ เปนตัวเลขชนิด int ch คือ ตัวอักษรที่ตองการนําไปแทนที่ ตองเปนขอมูลชนิด char string คือตัวแปร String class

ตัวอยางที่ 3-27 String str = “IPST”; void setup() { Serial.begin(9600); str.setCharAt(0,’1'); Serial.println(str); } void loop() {}

// ตังค ้ าอัตราบอดใหกับโมดูลสือสารข ่ อมูลผานพอรตอนุกรมเปน 9600 // แทนที่ตัวอักษรตําแหนง 0 ดวย 1 // ที่หนาตาง Serial monitor ของ Wiring IDE จะแสดงขอความ 1PST


   89

3.6.3.4 charAt() เปนคําสังคื ่ นคาเปนตัวอักษรใน string ที่อยูในตําแหนงที่กําหนดไว (index) รูปแบบ : string.charAt(index); โดยที่ index คือตําแหนงของตัวอักษร เปนตัวเลขชนิด int string คือตัวแปร String class

ตัวอยางที่ 3-28 String str = “IPST”; char c1 = str.charAt(0); // ตัวแปร c1 เก็บตัวอักษรตัวแรก char c2 = str.charAt(1); // ตัวแปร c2 เก็บตัวอักษรตัวที่สอง char c3 = str.charAt(str.length()-1); // ตัวแปร c3 เก็บตัวอักษรสุดทาย void setup() { Serial.begin(9600); // ตังค ้ าอัตราบอดใหกับโมดูลสือสารข ่ อมูลผานพอรตอนุกรมเปน 9600 Serial.println(c1); // สงขอมูลของอักษร I ไปยังหนาตาง Serial Terminal Serial.println(c2); // สงขอมูลของอักษร P ไปยังหนาตาง Serial Terminal Serial.println(c3); // สงขอมูลของอักษร T ไปยังหนาตาง Serial Terminal } void loop() {}


90  

3.6.3.5 indexOf() เปนคําสังค ่ นหาตําแหนง (index) ของตัวอักษรหรือขอความที่คนหา (str) ที่พบเปนที่แรกใน string ถาหาไมพบ คําสั่ง indexOf() จะคืนคาเปน -1 รูปแบบ : string.indexOf(str); หรือ

 โดยที่ str คือ ตัวอักษรหรือขอความที่ตองการคนหา fromIndex คือตําแหนงเริมต ่ นที่ใชในการคนหา เปนตัวเลขชนิด int string คือตัวแปร String class

ตัวอยางที่ 3-29 String str = “IPST”; int p1 = str.indexOf(“I”); int p2 = str.indexOf(“P”); int p3 = str.indexOf(“ST”); void setup() { Serial.begin(9600); Serial.println(p1, DEC); Serial.println(p2, DEC); Serial.println(p3, DEC); } void loop() {}

// ตัวแปร p1 เก็บตําแหนงของ I // ตัวแปร p2 เก็บตําแหนงของ P // ตัวแปร p3 เก็บตําแหนงของ ST // ตังค ้ าอัตราบอดเปน 9600 // สงขอมูลของเลข 0 ไปยังหนาตาง Serial Terminal // สงขอมูลของเลข 1 ไปยังหนาตาง Serial Terminal // สงขอมูลของเลข 2 ไปยังหนาตาง Serial Terminal


   91

3.6.3.6 equals() เปนคําสังเปรี ่ ยบเทียบ String กับขอความที่กําหนดไว (str) เนื่องจาก string ไมสามารถเปรียบ เทียบดวยการใชเครื่องหมาย == ได จึงตองใชคําสังนี ่ ้แทน equals() คืนคาเปนจริงเมือทั ่ ง้ 2 string เหมือนกัน และคืนคาเปนเท็จเมือทั ่ ง้ 2 string ไมเหมือนกัน ควรระวังเรื่องตัวพิมพเล็ก-ใหญในขอความทีนํ่ ามาเปรียบเทียบดวย รูปแบบ : string.equals(str); โดยที่ str คือ String ที่ตองการใชเปรียบเทียบ string คือตัวแปร String class

ตัวอยางที่ 3-30 String str1 = “IPST”; char str3[] = “IPST”; void setup() { Serial.begin(9600); if(str1.equals(str3) == true) { Serial.println(“Equal”); } else { Serial.println(“Not equal”); } if(str1.equals(“INEX”) == true) { Serial.println(“Equal”); } else { Serial.println(“Not equal”); } } void loop() {}

// ตังค ้ าอัตราบอดใหกับโมดูลสือสารข ่ อมูลเปน 9600 // ตรวจสอบวา str1 เหมือนกับ str3 หรือไม // ถาจริง แสดงขอความ Equal ที่หนาตาง Serial monitor

// ถาไมจริง แสดงขอความ Not equal // ตรวจสอบวา str1 เหมือนกับ IPST หรือไม // ถาจริง ใหแสดงขอความ Equal ที่หนาตาง Serial monitor

// ถาไมจริง แสดงขอความ Not equal ทีหน ่ าตาง Serial monitor


92  

3.6.3.7 startsWith() เปนคําสังตรวจสอบว ่ า String ขึนต ้ นดวยขอความทีกํ่ าหนดไว (str) หรือไม คําสัง่ startsWith() จะคืนคาเปนจริ งหาก string ขึ้นตนดวยขอความที่กําหนดไว และคืนคาเปนเท็จถาไมใช คําสั่ง startsWith() ตางกับ equals() ตรงที่ equals() ตองเปรียบเทียบใหเหมือนทุกตัวอักษรจึงจะคืนคาเปน จริง แต startsWith() ตรวจสอบเพียงตัวอักษรที่กําหนดไว รูปแบบ : string.startsWith(str); หรือ

string.startsWith(str, offset); โดยที่ str คือ String ที่ตองการเปรียบเทียบ fromIndex คือตําแหนงเริมต ่ นที่ใชในการเปรียบเทียบ เปนตัวเลขชนิด int string คือตัวแปร String class

ตัวอยางที่ 3-31 void setup() { Serial.begin(9600); String str1 = “IPST”; String str2 = “IP”; if(str1.startsWith(str2) == true) { Serial.println(“Starts with”); } else { Serial.println(“Not”); } } void loop() {}

// ตังค ้ าอัตราบอดเปน 9600 // ตรวจสอบวา str1 ขึนต ้ นดวย IN หรือไม // ถาจริง แสดงขอความ Starts with ทีหน ่ าตาง Serial monitor

// ถาไมเปนจริง แสดงขอความ Not ที่หนาตาง Serial monitor


   93

3.6.3.8 endsWith() เปนคําสังตรวจสอบว ่ า String ลงทายดวยขอความที่กําหนดไว (str) หรือไม คําสั่ง endsWith() คืนคาเปนจริงหาก string ลงทายดวยขอความทีกํ่ าหนดไว และคืนคาเปนเท็จถาไมใช คําสัง่ endsWith() จะตรวจสอบเพียงตัวอักษรที่กําหนดไวเทานั้นเหมือนกับคําสัง่ startsWith() รูปแบบ : string.endsWith(str); โดยที่ str คือ String ที่ตองการจะใชเปรียบเทียบ string คือตัวแปร String class

ตัวอยางที่ 3-32 void setup() { Serial.begin(9600); String str1 = “IPST”; String str2 = “ST”; if(str1.endsWith(str2) == true) { Serial.println(“Ends with”); } else { Serial.println(“Not”); } } void loop() {}

// ตังค ้ าอัตราบอดใหกับโมดูลสือสารข ่ อมูลอนุกรมเปน 9600 // ตรวจสอบวา str1 ลงทายดวย ST หรือไม // ถาเงือนไขเป ่ นจริง แสดงขอความนีที้ หน ่ าตาง Serial monitor

// ถาไมเปนจริง จะแสดงขอความนีที้ ่หนาตาง Serial monitor


94  

3.6.3.9 substring() เปนคําสังสร ่ างตัวอักษรใหมจากตัวอักษรในตัวแปรเดิม โดยคัดลอกตัวแปร string ตนฉบับจาก ตําแหนงเริมต ่ น (beginIndex) ทีกํ่ าหนดไวจนถึงตําแหนงสุดทายของตัวแปร string หากไมไดกําหนด พารามิเตอร endIndex ในกรณีที่มีการกําหนดพารามิเตอร endIndex คําสัง่ substring() จะคัดลอกจน ถึงตําแหนงสิ้นสุด (endIndex -1) ที่กําหนดไว ซึ่งจะนอยกวาตําแหนงที่สิ้นสุดที่กําหนดไว 1 ตําแหนง คําสัง่ substring() คืนคาเปน string ใหม รูปแบบ : string.substring(beginIndex); หรือ

string.substring(beginIndex, endIndex); โดยที่ beginIndex คือตําแหนงเริมต ่ นในการสรางตัวแปร string ใหม เปนตัวเลขชนิด int endIndex คือตําแหนงสินสุ ้ ดในการสรางตัวแปร string ใหม เปนตัวเลขชนิด int string คือตัวแปร String class

ตัวอยางที่ 3-33 void setup() { Serial.begin(9600); String str1 = “IPST”; String str2 = “Rabbit”; String ss1 = str1.substring(2); String ss2 = str2.substring(3); String ss3 = str1.substring(0,1); String result = ss1; result += ':'; result += ss2; result += ':'; result += ss3; Serial.println(result); } void loop() {}

// ตังค ้ าอัตราบอดใหกับโมดูลสือสารข ่ อมูลอนุกรมเปน 9600 // ตัวแปร ss1 เก็บคา ST // ตัวแปร ss2 เก็บคา bit // ตัวแปร ss3 เก็บคา IP

// แสดงขอความ ST:bit:IP ที่หนาตาง Serial monitor


   95

3.6.3.10 toCharArray() เปนคําสังคื ่ นคาเปนอะเรยของตัวแปรชนิด char ซึ่งประกอบดวย ตัวอักษรของ String ซึ่งก็คือ การแปลง String class เปนอะเรยของตัวแปรชนิด char คําสั่ง toCharArray() แตกตางกับคําสั่ง getBytes() ตรงที่คําสั่ง getBytes() จะไดผลลัพธเปนขอมูลชนิด byte แตคําสั่ง toCharArray() จะไดผลลัพธเปนขอมูลชนิด char รูปแบบ : string.toCharArray(); โดยที่ string คือตัวแปร String class

ตัวอยางที่ 3-34 void setup() { Serial.begin(9600); String str = “IPST”; char array [5]; str.toCharArray(array,5); Serial.println(array[1],BYTE); Serial.println(array); } void loop() {}

// ตังค ้ าอัตราบอดเปน 9600

// แสดงตัวอักษร P // แสดงขอความ IPST ที่หนาตาง Serial monitor


96  

3.6.3.11 toLowerCase() เปนคําสั่งแปลงตัวอักษรในตัวแปรชนิด string ใหเปนตัวพิมพเล็กทั้งหมด (lower case)

รูปแบบ : string.toLowerCase(); โดยที่ string คือตัวแปร String class

ตัวอยางที่ 3-35 void setup() { Serial.begin(9600); String str1 = “IPST”; str1.toLowerCase(); Serial.println(str1); } void loop() {}

// ตังค ้ าอัตราบอดใหกับโมดูลสือสารข ่ อมูลผานพอรตอนุกรมเปน 9600 // แปลงตัวอักษรเปนตัวพิมพเล็ก // แสดงขอความ ipst ที่หนาตาง Serial Terminal ของ Wiring IDE


   97

3.6.3.12 toUpperCase() เปนคําสั่งแปลงตัวอักษณในตัวแปรชนิด string ใหเปนตัวพิมพใหญทังหมด ้ (upper case)

รูปแบบ : string.toUpperCase() ; โดยที่ string คือตัวแปร String class

ตัวอยางที่ 3-36 void setup() { Serial.begin(9600); // ตังค ้ าอัตราบอดใหกับโมดูลสือสารข ่ อมูลผานพอรตอนุกรมเปน 9600 String str1= “Rabbit”; str1.toUpperCase(); // แปลงตัวอักษรเปนตัวพิมพใหญ Serial.println(str1); // แสดงขอความ RABBIT ที่หนาตาง Serial Terminal ของ Wiring IDE } void loop() {}


98  


  99

     การพัฒนาโปรแกรมภาษา C/C++ ดวย Wiring สําหรับชุดกลองสมองกล IPST-MicroBOX ทีได ่ ทําการปรับปรุงมาเปนแผงวงจร IPST++ ดําเนินการภายใตการสนับสนุนของไฟลไลบรารี ipst.h ทังนี ้ เพื ้ อช ่ วยลดขันตอนและความซั ้ บซอนในการเขียนโปรแกรมเพือควบคุ ่ มสวนตางๆ ของฮารดแวร โครงสรางของไฟลไลบรารี ipst.h แสดงดังรูป รายละเอียดของไฟลไลบรารียอยทังหมดมี ้ ดั้ งนี้

                                       


100  

4.1 ipst_lcd.h ไฟลไลบรารีของการแสดงผลที่โมดูล LCD เปนไฟลไลบรารีสนับสนุนชุดคําสังเกี ่ ่ยวกับการแสดงขอความทีโมดู ่ ล LCD กอนเรียกใชงาน ฟงกชันของ ่ ไลบรารีนีควรผนวกไฟล ้ ไลบรารีในตอนตนของโปรแกรมดวยคําสัง่ #include <ipst_lcd.h> หรือ #include <ipst.h> ฟงกชันที ่ สํ่ าคัญคือ lcd บรรจุฟงกชันสํ ่ าหรับการแสดงผลขอความทีโมดู ่ ล LCD แบบ 16 ตัวอักษร 2 บรรทัด รูปแบบ void lcd(char *p,...) พารามิเตอร p - รับรหัสสําหรับกําหนดกลุมขอความที่ตองการแสดงผลที่โมดูล LCD โดยสามารถกําหนดรูปแบบการ แทรกสัญลักษณพิเศษเพื่อรวมแสดงผลคาขอมูลตัวเลขรูปแบบอืนๆ ่ อันไดแก รหัสบังคับ การทํางาน %c หรือ %C รับคาการแสดงผลตัวอักษร 1 ตัว %d หรือ %D รับคาการแสดงผลตัวเลขฐานสิบในชวง -32,768 ถึง +32,767 %l หรือ %L รับคาการแสดงผลตัวเลขฐานสิบในชวง -2,147,483,648 ถึง +2,147,483,647 %f หรือ %F รับคาเพื่อแสดงผลขอมูลแบบจํานวนจริง (แสดงทศนิยม 3 หลัก) #c คําสังพิ ่ เศษเพื่อสั่งเคลียรขอความกอนแสดงผลในครั้งถัดไป #n คําสังพิ ่ เศษเพื่อสั่งตัดขอความไปแสดงผลยังบรรทัดที่ 2 (บรรทัดลาง)

ตัวอยางที่ 4-1 lcd(“Hello LCD”); ผลลัพธทีโมดู ่ ล LCD

// แสดงขอความ Hello LCD ที่โมดูล LCD

H e l l o o L C D rb o a r d r W i r i n g I / Ob R o b o t d


  101

ตัวอยางที่ 4-2 lcd(“abcdefghijklmnopqrstuvwxyz”); // แสดงผลขอความเมือสายอั ่ กขระเกิน 16 ตัวอักษร อักขระตัวถัดไปจะขึนบรรทั ้ ดที่ 2 (บรรทัดลาง) ทันที ผลลัพธทีโมดู ่ ล LCD abcdefghijklmnop q r s t u v w x yz R o b o t d

ตัวอยางที่ 4-3 lcd(“Value: %d unit “,518); // แสดงขอความรวมกับขอมูลตัวเลข (518) ที่โมดูล LCD ผลลัพธทีโมดู ่ ล LCD Value:g518kunitp q r s t u v w x yz R o b o t d

ตัวอยางที่ 4-4 lcd(“Value: %d “,analog(4)); ผลลัพธทีโมดู ่ ล LCD

// แสดงผลคาอะนาลอกชอง ADC4 ที่โมดูล LCD

Value:gxxxkunitp q r s t u v w x yz R o b o t d

โดยที่ xxx คือคาที่อานได มีคาตังแต ้ 0 ถึง 1023

ตัวอยางที่ 4-5 char c_test=’j’; lcd(“abcd%cxyz”,c_test);// แสดงอักขระ j รวมกับขอความอืนๆ ่ ผลลัพธทีโมดู ่ ล LCD

abcdjxyzxxkunitp q r s t u v w x yz R o b o t d


102  

ตัวอยางที่ 4-6 lcd(“Value: %f “,125.450); // แสดงขอความรวมกับตัวเลขที่โมดูล LCD (แสดงทศนิยม 3 หลัก) ผลลัพธทีโมดู ่ ล LCD Value:g125.450tp q r s t u v w x yz R o b o t d

ตัวอยางที่ 4-7 lcd(“count1: %d #ncount2: %d”,12,48); // แสดงขอความรวมกับ 2 รหัสควบคุม และคียพิเศษ #n // เพื่อกําหนดใหกลุมขอความที่ตอทาย #n จะถูกนํามาแสดงผลยังบรรทัดที่ 2 (บรรทัดลาง) ผลลัพธทีโมดู ่ ล LCD count1:112.450tp c o u n t 2 : x 48 R o b o t d

4.2 ipst_sleep.h ไฟลไลบรารียอยการหนวงเวลา เปนไฟลไลบรารีสนับสนุนชุดคําสังเกี ่ ่ยวกับการหนวงเวลา กอนเรียกใชงานควรผนวกไฟล ไลบรารีไวในตอนตนของโปรแกรมดวยคําสั่ง #include <ipst_sleep.h> หรือเรียก #include <ipst.h> ฟงกชันที ่ สํ่ าคัญคือ sleep เปนฟงกชันหน ่ วงเวลาโดยประมาณในหนวยมิลลิวินาที มีรายละเอียดดังนี้ รูปแบบ void sleep(unsigned int ms) พารามิเตอร ms - กําหนดคาเวลาที่ตองการหนวงในหนวยมิลลิวินาที มีคา 0 ถึง 65,535

ตัวอยางที่ 4-8 sleep(20); sleep(1000);

// หนวงเวลาประมาณ 20 มิลลิวินาที // หนวงเวลาประมาณ 1 วินาที


  103

4.3 in_out.h ไฟลไลบรารียอยสําหรับติดตอพอรต เปนไฟลไลบรารีสนับสนุนชุดคําสั่งอานและเขียนคากับพอรตอินพุตเอาตพุตของฮารดแวร Wiring I/O ซึงในที ่ ่นี้คือ แผงวงจร IPST++ กอนเรียกใชงานฟงกชันต ่ องผนวกไฟลไลบรารีนี้ไวใน ตอนตนของโปรแกรมดวยคําสั่ง #include <ipst_in_out.h> หรือเรียก #inclue <ipst.h> ฟงกชันที ่ สํ่ าคัญของไฟลไลบรารีนีประกอบด ้ วย

4.3.1 in เปนฟงกชันอ ่ านคาสถานะลอจิกของพอรตที่กําหนด รูปแบบ char in(x) พารามิเตอร x - กําหนดขาพอรตที่ตองการอานคา มีคาตังแต ้ 0 ถึง 50

การคืนคา เปน 0 หรือ 1

ตัวอยางที่ 4-9 char x; x = in(49);

// ประกาศตัวแปร x เพื่อเก็บคาผลลัพธจาการอานคาระดับสัญญาณ // อานคาดิจิตอลจากพอรตหมายเลข 49 แลวเก็บคาไวที่ตัวแปร x

ตัวอยางที่ 4-10 char x; x = in(50);

// ประกาศตัวแปร x เพื่อเก็บคาผลลัพธจาการอานคาระดับสัญญาณ // อานคาดิจิตอลจากพอรตหมายเลข 50 แลวเก็บคาไวที่ตัวแปร x

4.3.2 out เปนฟงกชันกํ ่ าหนดระดับสัญญาณหรือขอมูลดิจิตอลไปยังขาพอรตทีกํ่ าหนด รูปแบบ out(char _bit,char _dat)

พารามิเตอร _bit - กําหนดขาพอรตที่ตองการ มีคา 0 ถึง 50

ตัวอยางที่ 4-11 out(43,1); out(45,0);

// กําหนดใหขาพอรต 43 เปน “1” // กําหนดใหขาพอรต 45 เปน “0”


104  

4.3.3 sw1_press เปนฟงกชั่นวนตรวจสอบการกดสวิตช SW1 บนแผงวงจร IPST++ (หรือ Display-io หรือ Display-Motor ที่ติดตังบนแผงวงจรหลั ้ กของ IPST-MicroBOX) ตองรอจนกระทั่ง SW1 ถูกปลอยหลัง จากมีการกดสวิตช จึงจะผานพนการทํางานของฟงกชันนี ่ ้ไป รูปแบบ void sw1_press() ตัวอยางที่ 4-12 ............ sw1_press(); ................

// รอจนกระทั่งสวิตช SW1 ถูกกดและปลอย

4.3.4 sw2_press

เปนฟงกชันวนตรวจสอบการกดสวิ ่ ตช SW2 บนแผงวงจร IPST++ รูปแบบ void sw2_press() ตัวอยางที่ 4-13

.................. Sw2_press(); // รอจนกระทั่งสวิตช SW2 ถูกกดและปลอย .................

4.3.5 sw3_press

เปนฟงกชันวนตรวจสอบการกดสวิ ่ ตช SW3 บนแผงวงจร IPST++ รูปแบบ void sw3_press() ตัวอยางที่ 4-14

............ Sw3_press(); // รอจนกระทั่งสวิตช SW3 ถูกกดและปลอย .................


  105

4.3.6 sw1 เปนฟงกชันตรวจสอบการกดสวิ ่ ตช SW1 ในขณะใดๆ รูปแบบ char sw1()

การคืนคา เปน “0” เมื่อสวิตช SW1 ถูกกด และ เปน “1” เมือไม ่ มีการกดสวิตช SW1

ตัวอยางที่ 4-15 char x; x = sw1();

// ประกาศตัวแปร x เพื่อเก็บคาผลลัพธจากการอานคาดิจิตอล // อานคาสถานะของสวิตช SW1 มาเก็บไวที่ตัวแปร x

4.3.7 sw2 เปนฟงกชันตรวจสอบการกดสวิ ่ ตช SW2 ในขณะใดๆ รูปแบบ char sw2() การคืนคา เปน “0” เมื่อสวิตช SW2 ถูกกด และ เปน “1” เมือไม ่ มีการกดสวิตช SW2

ตัวอยางที่ 4-16 char x; // ประกาศตัวแปร x เพื่อเก็บคาผลลัพธจากการอานคาดิจิตอล x = sw2(); // อานคาสถานะของสวิตช SW2 มาเก็บไวที่ตัวแปร x

4.3.8 sw3 เปนฟงกชันตรวจสอบการกดสวิ ่ ตช SW3 ในขณะใดๆ รูปแบบ char sw2() การคืนคา เปน “0” เมื่อสวิตช SW2 ถูกกด และ เปน “1” เมื่อไมมีการกดสวิตช SW3

ตัวอยางที่ 4-17 char x; // ประกาศตัวแปร x เพื่อเก็บคาผลลัพธจากการอานคาดิจิตอล x = sw3(); // อานคาสถานะของสวิตช SW2 มาเก็บไวที่ตัวแปร x


106  

4.4 ipst_analog.h ไฟลไลบรารีจัดการสัญญาณอะนาลอก เปนไฟลไลบรารีสนับสนุนชุดคําสังที ่ ่เกี่ยวกับการอานคาอินพุตอะนาลอก ซึ่งใชในการอาน คาจากตัวตรวจจับทีให ่ ผลการทํางานในรูปแรงดันไฟฟาในยาน 0 ถึง +5V กอนเรียกใชงานตองผนวก ไฟลไลบรารีไวในตอนตนของโปรแกรมดวยคําสัง่ #include <ipst_analog.h> หรือ #inclue <ipst.h> ฟงกชันที ่ สํ่ าคัญของไฟลไลบรารีนีประกอบด ้ วย

4.4.1 analog เปนฟงก ชั่นอ านคาขอมูลดิจิตอลที่ไดจากการกระบวนการแปลงสัญญาณอะนาลอกของ ไมโครคอนโทรลเลอรทีขาพอร ่ ต ADC0 ถึง ADC7 รูปแบบ unsigned int analog(unsigned char channel) พารามิเตอร channel - กําหนดชองอินพุตอะนาลอกที่ตองการ มีคา 0 ถึง 7 ซึงตรงกั ่ บขาพอรต ADC0 ถึง ADC7

การคืนคา เป นขอมูลที่ ไดจากการแปลงสัญญาณของโมดูลแปลงสัญญาณอะนาลอกเปนดิจิตอลภายในไมโคร คอนโทรลเลอรจากชองอินพุตที่กําหนด โดยขอมูลมีความละเอียด 10 บิต ดังนันค ้ าที่เปนไปไดคือ 0 ถึง 1,023

ตัวอยางที่ 4-18 int val=0; // กําหนดตัวแปรสําหรับเก็บคาของอินพุตอะนาลอกทีได ่ จากการแปลงสัญญาณแลว val = analog(2); // อานคาของอินพุตอะนาลอกชอง 2 มาเก็บไวที่ตัวแปร val

4.4.2 knob เปนฟงกชั่นสําหรั บอานคาขอมูลดิจิตอลที่ไดจากการแปลงสัญญาณอะนาลอกของไมโคร คอนโทรลเลอรทีขาพอร ่ ต ADC7 ซึงต ่ อกับตัวตานทานปรับคาไดหรือเรียกวาชองอินพุตนีว้ า KNOB รูปแบบ unsigned int knob() การคืนคา เปนขอมูลที่ไดจากการแปลงสัญญาณอะนาลอกเปนดิจิตอลจากชอง KNOB (ADC7) มีคา 0 ถึง 1,023

ตัวอยางที่ 4-19 int val=0; val = knob();

// กําหนดตัวแปรสําหรับเก็บคาของอินพุตอะนาลอกทีได ่ จากการแปลงสัญญาณแลว // อานคาจากอินพุต knob ซึงผ ่ านการแปลงเปนขอมูลดิจิตอลแลวมาเก็บไวทีตั่ วแปร val


  107

4.5 ipst_motor.h เปนไฟลไลบรารีชุดคําสังควบคุ ่ มมอเตอรไฟตรง ตองผนวกไฟลไลบรารีไวในตอนตนของ โปรแกรมดวยคําสัง่ #include <motor.h> หรือ #inclue <atx.h>

4.5.1 การเชือมต ่ อทางฮารดแวร ไฟลไลบรารีนี้รองรับการขับมอเตอรไฟตรงของแผงวงจร IPST++ จํานวน 2 ชองคือ ชอง 1 และ 2 ใน 2 วิธีการเชือมต ่ อ ดังนี้ 1. กรณีใชแผงวงจร IPST++ ทีมาจากแผงวงจรหลั ่ กกับแผงวงจร Display-io จะตองใชแผงวงจร ขับมอเตอร ZX-DCM2 รวมดวย มีการตอวงจรเพิ่มเติมดังรูปที่ 4-2 ซึ่งสรุปไดดังนี้ (ก) สําหรับมอเตอรชอง 1  ตอขาพอรต PD2 ของแผงวงจร MicroBOX กับอินพุต DIR1A  ตอขาพอรต PD3 ของแผงวงจร MicroBOX กับอินพุต DIR1B  ตอขาพอรต PD4 ของแผงวงจร MicroBOX กับอินพุต PWM1E

(ข) สําหรับมอเตอรชอง 2  ตอขาพอรต PD7 ของแผงวงจร MicroBOX กับอินพุต DIR2A  ตอขาพอรต PD6 ของแผงวงจร MicroBOX กับอินพุต DIR2B  ตอขาพอรต PD5 ของแผงวงจร MicroBOX กับอินพุต PWM2E

2. กรณีใชแผงวงจร IPST++ ที่มาจากแผงวงจรหลักกับแผงวงจร Display-MOTOR ซึ่งมีวงจร ขับมอเตอรในตัว จึงใชงานไดทันที ดังแสดงตําแหนงเชือมต ่ อมอเตอรในรูปที่ 4-3


108  

DC MOTOR 6-12V

PB4

TxD

PB3

PWM2 DIR2A DIR2B 2E +VM

PA1 PA3 PA5

L293D/SN754410

PB1

PB0 PA0 PA2 PA4

+VM

2B 2A 2E G

IPST MicroBOX

ON

OFF

+5V

GND PC0 PC1 PC2 PC3 PC4 PC5 PC6 PC7 +5V

+ Vin -

1B 1A 1E +5

+

ISP

PB2

OUT1

ZX-DCM2 DIR1B DIR1A PWM1 1E

ATMEGA16 PA7

OUT2

RESET

PD3

+

PD2

PD5

PORTC

+

PD4

PD7

PD1

PD6

DC input

DC MOTOR 6-12V

PA6

รูปที่ 4-2 การตอวงจรเพื่อใชงานแผงวงจร MicroBOX ขับมอเตอรไฟตรงผานแผงวงจร ZX-DCM2 ในชุดกลองสมองกล IPST-MicroBOX

Display-MOTOR

แผงวงจรแสดงผลและควบคุมมอเตอร PORTC

PA7

Vm OUT

GND GND PC0 PC0 PC1 PC1 PC2 PC2 PC3 PC3 PC4 PC4 PC5 PC5 PC6 PC6 PC7 PC7 +5V +5V

PA6

IPST MicroBOX PA4

PA5

KNOB PA7

DC input

OFF

ON

ON

SCL DC INPUT

PA2

PA1

PA0

Over 7.5V

++ Vin -

PA3

SDA RS-232 LOW BATT.

M2 M1

PD7

PD1

PD6

PD0

PD5

TxD

PD4

RxD

PD3

PB4

RESET

สวนของวงจร ขับมอเตอรไฟตรง

MOTOR OUTPUT

PD2

B0 B1 B2 B3 B4

DisplayMotor

PB2 SW3

+ -

PB0

PB3

SW2

S

PB1

SW1

SERVO

ATMEGA16

I P S T - B O T o ro b o t D i s p l a y - MO T E R a r d

จุดตอมอเตอร ไฟตรง 2 ตัว

LED แสดงสถานะการทํางาน สีเขียว : หมุนไปขางหนา สีแดง : หมุนกลับทาง

รูปที่ 4-3 แสดงสวนของวงจรขับมอเตอรบนแผงวงจร Display-MOTOR


  109

4.5.2 motor เปนฟงกชันขั ่ บเคลือนมอเตอร ่ ไฟตรง รูปแบบ void motor(char _channel,int _power) พารามิเตอร _channel - กําหนดชองเอาตพุตมอเตอรไฟตรงของแผงวงจร IPST++ มีคา 1 และ 2 _power - กําหนดกําลังขับมอเตอร มีคาในชวง -100 ถึง 100 ถากําหนดคา _power เปนบวก (1 ถึง 100) ทําใหมอเตอรหมุนไปในทิศทางหนึง่ ถากําหนดคา _power เปนลบ (-1 ถึง -100) มอเตอรจะถูกขับใหหมุนไปในทิศทางตรงขาม ถากําหนดคา _power เปน 0 มอเตอรหยุดหมุน ไมแนะนําใหกําหนดคาเปน 0 หากตองการใหมอเตอร หยุดหมุนควรเรียกใชฟงกชัน่ motor_stop

ตัวอยางที่ 4-20 motor(1,60); motor(1,-60);

// ขับมอเตอรชอง 1 ดวยกําลัง 60% ของกําลังสูงสุด // ขับมอเตอรชอง 1 ดวยกําลัง 60% มีทิศทางการหมุนตรงขามกับคําสังก ่ อนหนา

ตัวอยางที่ 4-21 motor(2,100);

// ขับมอเตอรชอง 2 ดวยกําลัง 100% อันเปนคากําลังสูงสุด

4.5.3 motor_stop เปนฟงกชันหยุ ่ ดขับมอเตอร รูปแบบ void motor_stop(char _channel) พารามิเตอร _channel - กําหนดชองเอาตพุตมอเตอรไฟตรง มีคา 1, 2 และ ALL โดย ALLเปนการเลือกใหมอเตอร ทังหมดหยุ ้ ดทํางาน

ตัวอยางที่ 4-22 motor_stop(1); motor_stop(2);

// หยุดขับมอเตอรชอง 1 // หยุดขับมอเตอรชอง 2

ตัวอยางที่ 4-23 motor_stop(ALL);

// มอเตอรทั้ง 2 ชองหยุดทํางานพรอมกัน


110  

4.6 ipst_SoftwareServo.h ไฟลไลบรารีขับเซอรโวมอเตอร เปนไฟลไลบรารีควบคุมเซอรโวมอเตอร มีฟงกชันสนั ่ บสนุนการควบคุมตําแหนงแกนหมุน ของเซอรโวมอเตอร ควบคุมได 5 ตัวในเวลาเดียวกัน กอนใชงานตองผนวกไลบรารีไวในตอนตนของ โปรแกรมดวยคําสัง่ #include <ipst_SoftwareServo.h> หรือ #include <ipst.h> ในไฟลไลบรารีนี้มี 2 ฟงกชันคื ่ อ servo และ servoRefresh

4.6.1 การเชือมต ่ อทางฮารดแวร

AA

AA

AA DC input

PORTC

OFF

PA7

PA6

ON

ON Vm OUT

SCL

IPST MicroBOX

KNOB PA7

สายไฟบวก (สีแดง)

สายไฟลบ (สีดํา)

GND GND PC0 PC0 PC1 PC1 PC2 PC2 PC3 PC3 PC4 PC4 PC5 PC5 PC6 PC6 PC7 PC7 +5V +5V

PA4

PA5

DC INPUT

SDA

PA0

Over 7.5V

I P S T - B O T o ro b o t ATMEGA16

PA2

PA1

RS-232 LOW BATT.

++ Vin -

PA3

Display-MOTOR

M2

PD7

จุดตอเซอรโวมอเตอร 5 ตัว (PB0 ถึง PB4)

M1

PD6

PD1

PD5

PD0

PD4

TxD

ไฟแจงระดับของแบตเตอรี่

MOTOR OUTPUT PD3

RxD

สวิตชเปด-ปด

แผงวงจรแสดงผลและ ควบคุมมอเตอร

PD2

B0 B1 B2 B3 B4

DisplayMotor

SW3

+ -

PB2

PB4

RESET

SW2

S

PB0

PB3

SW1

SERVO

D i s p l a y - MO T E R a r d PB1

แผงวงจรหลัก MicroBOX อยู ดานลาง เมื่อตอกับแผงวงจร Display-MOTOR แล ว การ จายไฟเลี้ยงใหกระทําผานจุด ต อ ไฟเลี้ ยง DC INPUT บน แผงวงจร Display-MOTOR แทน

AA

กะบะถานขนาด AA 5 กอน  ถาใชแบตเตอรี่แบบอัลคาไลน จะไดแรงดัน +7.5V (1.5V x5)  ถาใชแบตเตอรี่แบบประจุ ได จะไดแรงดัน +6V (1.2V x5)

AA

ไลบรารี จะใชงานไดกับแผงวงจร IPST++ ที่มาจากการประกอบกันของแผงวงจรหลัก MicroBOX กับแผงวงจร Display-MOTOR มีตัวอยางการตอใชงานแสดงในรูปที่ 4-4

เซอรโวมอเตอร

SERVO MOTOR Standard

รูปที่ 4-4 แสดงการตอใชงานแผงวงจรหลัก MicroBOX กับแผงวงจร Display-MOTOR และเซอรโวมอเตอร


  111

4.6.2 servo เปนฟงกชันกํ ่ าหนดตําแหนงแกนหมุนของเซอรโวมอเตอร รูปแบบ void servo(unsigned char _ch, int _pos) พารามิเตอร _ch - ชองเอาตพุตเซอรโวมอเตอร มีคา 0 ถึง 4 _pos - กําหนดตําแหนงแกนหมุนของเซอรโวมอเตอร มีคาในชวง 0 ถึง 180 และ -1 ถากําหนดเปน -1 หมายถึง ไมใชงานเซอรโวมอเตอรที่ชองนันๆ ้

4.6.3 servoRefresh เปนฟงกชันเตรี ่ ยมความพรอมในการขับเซอรโวมอเตอรของแผงวงจร IPST++ จะตองเรียกใช ฟงกชันนี ่ ้กอนใชฟงกชัน่ servo เสมอ รูปแบบ void servoRefresh ตัวอยางที่ 4-24 #include <ipst.h> unsigned int pos = 20; void setup() { lcd_clear(); } void loop() { servoRefresh(); sleep(100); servo(0,pos); sleep(100); servo(0,0); sleep(100); }

// ผนวกไฟลไลบรารีหลัก "ipst.h" // กําหนดตัวแปรสําหรับควบคุมตําแหนงของเซอรโวมอเตอร // ลางขอมูลที่ถูกสงไปยังโมดูล LCD กอนหนานี้

// ลางขอมูลตําแหนงลาสุดที่สงไปยังเซอรโวมอเตอร // ใหพรอมที่จะรับคาตําแหนงใหม // กําหนดตําแหนงการขับเซอรโวมอเตอรชอง 0 จากตัวแปร pos // หนวงเวลา // กําหนดตําแหนงของเซอรโวมอเตอรชอง 0 กลับไปยังตําแหนง 0 // หนวงเวลา


112  

4.7 ipst_sound.h ไฟลไลบรารีกําเนิดสัญญาณเสียง เปนไฟลไลบรารีสนับสนุนชุดคําสังเกี ่ ่ยวกับการกําเนิดเสียงของแผงวงจร ATX กอนใชงาน ตองผนวกไฟลไลบรารีไวในตอนตนของโปรแกรมดวยคําสั่ง #include <ipst_sound.h> หรือ #include <ipst.h>

4.7.1 beep เปนฟงกชันกํ ่ าเนิดเสียง “ติด” ๊ ซึ่งมีความถี่ 500Hz นาน 100 มิลลิวินาที ที่ขาพอรตใดๆ รูปแบบ void beep()

4.7.2 sound เปนฟงกชันกํ ่ าเนิดสัญญาณเสียงที่กําหนดความถี่และระยะเวลาในการกําเนิดสัญญาณได รูปแบบ void sound(int freq,int time) พารามิเตอร freq - กําหนดความถีสั่ ญญาณเสียง มีคา 0 ถึง 32,767 time - กําหนดคาเวลาในการกําเนิดสัญญาณเสียงในหนวย 1 มิลลิวินาที มีคา 0 ถึง 32,767

ตัวอยางที่ 4-25 beep(); // กําเนิดเสียงความถี่ 500Hz นาน 100 มิลลิวินาที sound(1200,500); // กําเนิดสัญญาณเสียงความถี่ 1200Hz นาน 500 มิลลิวินาที


  113

4.8 serial.h ไฟลไลบรารีสือสารข ่ อมูลผานโมดูลสือสารข ่ อมูลพอรตอนุกรม หรือ UART เปนไฟลไลบรารีสนับสนุนชุดคําสังเกี ่ ่ยวกับการรับสงขอมูลผานโมดูลสือสารข ่ อมูลอนุกรม (UART) กอนเรียกใชงานตองผนวกไฟลไลบรารีไวในตอนตนของโปรแกรมดวยคําสัง่ #include <ipst_serial.h> หรือ #include <ipst.h>

4.8.1 การเชือมต ่ อทางฮารดแวร มีใหใชงานเพียงชองเดียวคือ จุดตอพอรตอนุกรมบนแผงวงจร Display-io หรือ Display-MOTOR โดยใชสาย CX-4 ตอกับพอรตอนุกรมของคอมพิวเตอร หรือตอผานตัวแปลงสัญญาณ UCON-232S หากคอมพิวเตอรทีใช ่ งานมีเฉพาะพอรต USB เปนจุดตอเดียวกับทีใช ่ ในการอัปโหลดโปรแกรม ดังใน รูปที่ 4-5 ตอเขากับพอรตอนุกรม ของคอมพิวเตอรโดยตรง

สาย CX-4 ปรับความสวางจอแสดงผล ของโมดูล LCD

UCON-232S

ตอสาย CX-4 เขากับ UCON-232S ตัวแปลงสัญญาณพอรต USB เปนพอรตอนุกรม ในกรณีที่คอมพิวเตอรไมมีพอรตอนุกรม

  DC input

PORTC

OFF

PA7

PA6

ON

IPST MicroBOX PA4

PA5

GND PC0 PC1 PC2 PC3 PC4 PC5 PC6 PC7 +5V

SCL

KNOB PA7 LCD

SDA

RS-232

PA0

ATMEGA16

PA2

PA1

+ Vin -

PA3

I P S T - M i c r oB O X

TxD

PD0

PD1

PD7

RxD

PD6

PB4

RESET

PD5

PB2 SW3

PD4

PB0

PB3

SW2

PD3

PB1

SW1

PD2

D i s p l a y - io B o a r d

ตอกับพอรต USB ของคอมพิวเตอร

    แผงวงจร Display-io หรือ Display-MOTOR

แผงวงจรหลัก MicroBOX อยูดานลาง

รูปที่ 4-5 การตอวงจรเพือทดสอบและใช ่ งานไลบรารี uart สําหรับสือสารข ่ อมูลอนุกรมกับคอมพิวเตอร


114  

4.8.2 uart เปนฟงกชันสํ ่ าหรับสงขอมูลสายอักขระออกจากโมดูล UART มีอัตราบอดเริ่มตนที่ 115,200 บิตตอวินาที รูปแบบ void uart(char *p,...) พารามิเตอร p - รับรหัสของกลุมขอความที่ตองการสงออกจากภาคสงของโมดูล UART0 โดยสามารถกําหนดรูปแบบ การแทรกสัญลักษณพิเศษเพื่อใชรวมในการแสดงผลไดดังนี้ รหัสบังคับ การทํางาน %c หรือ %C แสดงผลตัวอักษร 1 ตัว %d หรือ %D แสดงผลตัวเลขฐานสิบชวงตังแต ้ -32,768 ถึง +32,767 %l หรือ %L แสดงผลตัวเลขฐานสิบชวงตังแต ้ -2,147,483,648 ถึง +2,147,483,647 %f หรือ %F แสดงผลขอมูลแบบจํานวนจริง(แสดงทศนิยม 3 หลัก) \r กําหนดใหขอความชิดไปทางดานซายของบรรทัด \n กําหนดใหขอความขึนบรรทั ้ ดใหม

4.8.3 uart_set_baud เปนฟงกชันกํ ่ าหนดอัตราบอดในการสื่อสารของโมดูล UART กับคอมพิวเตอร รูปแบบ void uart_set_baud(unsigned int baud) พารามิเตอร baud - อัตราบอดในการสือสารของโมดู ่ ล UART0 กับคอมพิวเตอร มีคา 2400 ถึง 115,200

ตัวอยางที่ 4-26 uart_set_baud(4800);

// กําหนดอัตราบอดในการสือสารข ่ อมูลเปน 4,800 บิตตอวินาที


  115

4.8.3 uart_available เปนฟงกชันตรวจสอบการรั ่ บขอมูลเขามาของโมดูล UART0 เมื่อติดตอกับคอมพิวเตอร รูปแบบ unsigned char uart_available(void) การคืนคา - เปน “0” เมือยั ่ งไมมีขอมูลเขามา - มากกวา 0 เมือมี ่ ขอมูลเขามา โดยมีคาเทากับจํานวนของอักขระที่ไดรับ

ตัวอยางที่ 4-27 char x =uart_available(); // ตรวจสอบวา มีขอมูลเขามาทางภาครับของโมดูล UART0 หรือไม ถา x มีคามากกวา 0 แสดงวา // มีขอมูลเขามายังภาครับแลว ควรอานขอมูลออกดวยฟงกชัน่ uart_getkey ในลําดับถัดไปทันที

4.8.4 uart_getkey เปนฟงกชันอ ่ านขอมูลจากบัฟเฟอรตัวรับของโมดูล UART0 รูปแบบ char uart_getkey(void) การคืนคา - เปน “0” เมือไม ่ มีการรับอักขระใดๆ เขามายังวงจรภาครับของโมดูล UART - เปนคาของอักขระที่รับไดในรูปแบบของรหัสแอสกี้

ตัวอยางที่ 4-28

}

#include <atx.h> void setup() { } void loop() { if(uart_available()) { if(uart_getkey()==’a’) { lcd(“Key a Active!”); sleep(1000); } else { lcd(“#c”); } }

// เรียกใชฟงกชันพื ่ ้นฐาน // ลูปการทํางานหลัก // ตรวจสอบวามีขอมูลเขามาหรือไม // ตรวจจับการกดคีย a วา ถูกกดหรือไม // แสดงขอความเพื่อตอบสนองตอการตรวจพบวามีการคีย a // หนวงเวลาแสดงขอความประมาณ 1 วินาที // เคลียรขอความที่หนาจอโมดูล LCD


116  


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.