ความรู้เกี่ยวกับภาษา C/C++ และฟังก์ชั่นของ สำ�หรับชุดกล่องสมองกล
Arduino IDE
• โครงสร้างภาษา C/C++ ที่ใช้ ในซอฟต์แวร์ Arduino IDE • ข้อควรรู้เกี่ยวกับตัวแปรในภาษา C/C++ ของ Arduino • ฟังก์ชั่นพื้นฐานของ Arduino และ ตัวอย่างค�ำสั่ง
www.ipst-microbox.com
Arduino IDE 1
Arduino IDE Arduino Programming Reference with IPST-MicroBOX Secondary Education (SE)
2 Arduino IDE
ความรูเกี่ยวกับภาษา C/C++ และฟงกชันของ ่ Arduino IDE สําหรับ ชุดกลองสมองกล IPST-MicroBOX (SE) ISBN 974 - 92023 - 0 -9
สงวนลิขสิทธิ์ตาม พ.ร.บ. ลิขสิทธิ์ พ.ศ. 2521 หามการลอกเลียนไมวาสวนหนึ่งสวนใดของหนังสือเลมนี้ นอกจากจะไดรับอนุญาต ใครควรใชหนังสือเลมนี้ 1. นักเรียน นิสิต นักศึกษา และบุคคลทัวไปที ่ มี่ ความสนใจในการนําไมโครคอนโทรลเลอรไปประยุกตใชในการทดลอง ทางวิทยาศาสตร หรือสนใจในการเรียนรูและทดลองวิ ยาศาสตรในแนวทางใหมที่ใชกิจกรรมเปนสื่อ โดยมีไมโคร คอนโทรลเลอรเปนสวนประกอบ 2. สถาบันการศึกษา โรงเรียน วิทยาลัย มหาวิทยาลัย ทีมี่ การเปดการเรียนการสอนวิชาอิเล็กทรอนิกสหรือภาควิชา วิศวกรรมอิเล็กทรอนิกสและคอมพิวเตอร 3. คณาจารยทีมี่ ความตองการศึกษา และเตรียมการเรียนการสอนวิชาไมโครคอนโทรลเลอร รวมถึงวิทยาศาสตร ประยุกตที่ตองการบูรณาการความรูทางอิเล็กทรอนิกส-ไมโครคอนโทรลเลอร-การเขียนโปรแกรมคอมพิวเตอรการทดลองทางวิทยาศาสตร ในระดับมัธยมศึกษา อาชีวศึกษา และปริญญาตรี ดําเนินการจัดพิมพและจําหนายโดย บริษัท อินโนเวตีฟ เอ็กเพอริเมนต จํากัด 108 ซ.สุขุมวิท 101/2 ถ.สุขุมวิท แขวงบางนา เขตบางนา กรุงเทพฯ 10260 โทรศัพท 0-2747-7001-4 โทรสาร 0-2747-7005 รายละเอียดที่ปรากฏในหนังสือความรูเกี ยวกั ่ บภาษา C/C++ และฟงกชันของ ่ Arduino IDE สําหรับชุดกลอง สมองกล IPST-MicroBOX (SE) ผานการตรวจทานอยางละเอียดและถวนถี่ เพือให ่ มีความสมบูรณและถูกตอง มากทีสุ่ ดภายใตเงือนไขและเวลาที ่ พึ่ งมีกอนการจัดพิมพเผยแพร ความเสียหายอันอาจเกิดจาก การนําขอมูลใน หนังสือเลมนี้ไปใช ทางบริษัท อินโนเวตีฟ เอ็กเพอริเมนต จํากัด มิไดมีภาระในการรับผิดชอบแตประการใด ความผิดพลาดคลาดเคลือนที ่ อาจมี ่ และไดรับการจัดพิมพเผยแพรออกไปนัน้ ทางบริษัทฯ จะพยายามชีแจงและ ้ แกไขในการจัดพิมพครังต ้ อไป
Arduino IDE 3
การนําเสนอขอมูลเกียวกั ่ บขอมูลทางเทคนิคและเทคโนโลยีในหนังสือเลมนี้ เกิดจากความตอง การทีจะอธิ ่ บายกระบวนการและหลักการทํางาน ของอุปกรณในภาพรวมดวยถอยคําทีง่ ายเพือสร ่ าง ความเขาใจแกผูอ าน ดังนันการแปลคํ ้ าศัพททางเทคนิคหลายๆ คําอาจไมตรงตามขอบัญญัติของราช บัณฑิตยสถาน และมีหลายๆ คําที่ยังไมมีการบัญญัติอยางเปนทางการ คณะผูเขี ยนจึงขออนุญาต บัญญัติศัพทขึนมาใช ้ ในการอธิบาย โดยมีขอจํากัดเพืออ ่ างอิงในหนังสือเลมนีเท ้ านัน้ ทังนี ้ สาเหตุ ้ หลักของขอชีแจงนี ้ มาจาก ้ การรวบรวมขอมูลของอุปกรณในระบบสมองกลฝงตัว และเทคโนโลยีหุนยนต สําหรับการศึกษาเพือนํ ่ ามาเรียบเรียงเปนภาษาไทยนันทํ ้ าไดไมงายนัก ทางคณะ ผูเขี ยนตองทําการรวบรวมและทดลองเพือให ่ แนใจวา ความเขาใจในกระบวนการทํางานตางๆ นันมี ้ ความ คลาดเคลือนน ่ อยทีสุ่ ด เมือต ่ องทําการเรียบเรียงออกมาเปนภาษาไทย ศัพททางเทคนิคหลายคํามีความหมายทีทั่ บซอน กันมาก การบัญญัติศัพทจึงเกิดจากการปฏิบัติจริงรวมกับความหมายทางภาษาศาสตร ดังนันหากมี ้ ความ คลาดเคลือนหรื ่ อผิดพลาดเกิดขึน้ ทางคณะผูเขี ยนขอนอมรับและหากไดรับคําอธิบายหรือชีแนะจากท ้ าน ผูรู จะได ทําการชีแจงและปรั ้ บปรุงขอผิดพลาดทีอาจมี ่ เหลานันโดยเร็ ้ วทีสุ่ ด ทังนี ้ เพื ้ ่อใหการพัฒนาสือทางวิ ่ ชาการ โดยเฉพาะอยางยิ่งกับความรูของเทคโนโลยีสมัยใหม สามารถดําเนินไปไดอยางตอเนือง ่ ภายใตการมีสวนรวมของผูรู ในทุ กภาคสวน บริษัท อินโนเวตีฟ เอ็กเพอริเมนต จํากัด
หนังสือเลมนี้เปนสวนหนึ่งของชุดกลองสมองกล IPST-MicroBOX Seconday Edition (SE) โดยใชประกอบใน การเรียนรูและฝ กฝนเกียวกั ่ บการเขียนและพัฒนาโปรแกรมภาษา C/C++ เพือนํ ่ ามาพัฒนาโปรแกรมสําหรับกําหนด และควบคุมการทํางานของแผงวงจรตางๆ ในชุดกลองสมองกล IPST-MicroBOX (SE)
4 Arduino IDE
คําชีแจงจากคณะผู ้ เขี ยน/เรียบเรียง..................................................................................................3 บทที่ 1
โครงสรางภาษา C/C++ ทีใช ่ ในซอฟตแวร Arduino IDE.......................................................5
บทที่ 2
ขอควรรูเกี ยวกั ่ บตัวแปรในภาษา C/C++ ของ Arduino...................................................39
บทที่ 3
ฟงกชันพื ่ นฐานของ ้ Arduino และตัวอยางคําสัง.......................................................... ่ 55
Arduino IDE 5
Arduino ในการเขียนโปรแกรมสําหรับแผงวงจร IPST-SE จะตองเขียนโปรแกรมโดยใชภาษา C/C++ ของ Arduino (Arduino programming language) เวอรชัน 1.0 ขึนไป ้ ภาษาของ Arduino แบงไดเปน 2 สวน หลักคือ 1. โครงสรางภาษา (structure) ตัวแปรและคาคงที่ 2. ฟงกชั่น (function) ภาษาของ Arduino จะอางอิงตามภาษา C/C++ จึงอาจกลาวไดวาการเขียนโปรแกรมสําหรับ Arduino (รวมถึงแผงวงจร IPST-SE) ก็คือการเขียนโปรแกรมภาษา C โดยเรียกใชงานฟงกชั่นและ ไลบรารีทีทาง ่ Arduino ไดเตรียมไวใหแลว ซึงสะดวก ่ ทําใหผูที ไม ่ มีความรูด านไมโครคอนโทรลเลอร อยางลึกซึ้งสามารถเขียนโปรแกรมสั่งงานได
1.1 โครงสรางโปรแกรมของ Arduino โปรแกรมของ Arduino แบงไดเปนสองสวนคือ void setup()
และ void loop()
โดยฟงกชัน่ setup() เมือโปรแกรมทํ ่ างานจะทําคําสังของฟ ่ งกชันนี ่ เพี ้ ยงครังเดี ้ ยว ใชในการ กําหนดคาเริมต ่ นของการทํางาน สวนฟงกชัน่ loop() เปนสวนทํางาน โปรแกรมจะกระทําคําสังใน ่ ฟงกชั่นนี้ตอเนื่องกันตลอดเวลา โดยโคดโปรแกรมที่ทํางานใน loop()มักเปนคําสั่งอานคาอินพุต ประมวลผล สั่งงานเอาตพุต ฯลฯ สวนกําหนดคาเริมต ่ น เชน ตัวแปร จะตองเขียนไวทีส่ วนหัวของโปรแกรม กอนถึงตัวฟงกชัน่ นอกจากนั้นยังตองคํานึงถึงตัวพิมพเล็ก-ใหญของตัวแปรและชื่อฟงกชั่นใหถูกตองดวย
6 Arduino IDE
1.1.1 สวนของฟงกชัน่ setup() ฟงกชั่นนี้จะเขียนที่สวนตนของโปรแกรม ทํางานเมื่อโปรแกรมเริมต ่ นเพียงครั้งเดียว ใชเพือ่ กําหนดคาของตัวแปร, โหมดการทํางานของขาตางๆ หรือเริ่มตนเรียกใชไลบรารี ฯลฯฯ ตัวอยางที่ 1-1 int buttonPin = 3; void setup() { Serial.begin(9600); pinMode(buttonPin, INPUT); } void loop() { if (digitalRead(buttonPin) == HIGH) Serial.write('H'); else Serial.write('L'); delay(1000); }
ในขณะทีโปรแกรมภาษา ่ C มาตรฐานทีเขี ่ ยนบน AVR GCC (เปนโปรแกรมภาษา C ทีใช ่ คอม ไพเลอรแบบ GCC สําหรับไมโครคอนโทรลเลอร AVR) จะเขียนไดดังนี้ int main(void) { init(); setup(); for (;;) loop(); return ; }
ตรงกับ void
setup()
ตรงกับ void
loop()
Arduino IDE 7
1.1.2 สวนของฟงกชัน่ loop() หลังจากทีเขี ่ ยนฟงกชัน่ setup()ทีกํ่ าหนดคาเริมต ่ นของโปรแกรมแลว สวนถัดมาคือฟงกชัน่ ่ ภายในฟงกชั่น loop() ซึ่งมีการทํางานตรงตามชื่อคือ จะทํางานตามฟงกชั่นนี้วนตอเนืองตลอดเวลา นี้จะมีโปรแกรมของผูใช เพือรั ่ บคาจากพอรต ประมวล แลวสังเอาต ่ พุตออกขาตางๆ เพือควบคุ ่ มการ ทํางานของบอรด ตัวอยางที่ 1-2 int buttonPin = 3; // กําหนดชื่อตัวแปรใหขาพอรต 3 และชนิดของตัวแปร void setup() { Serial.begin(9600); pinMode(buttonPin, INPUT); } // ลูปตรวจสอบการกดสวิตชทีขาพอร ่ ตซึงถู ่ กประกาศดวยตัวแปร buttonPin void loop() { if (digitalRead(buttonPin) == HIGH) serial.Write('H'); else Serial.write('L'); delay(1000); }
8 Arduino IDE
1.2 คําสังควบคุ ่ มการทํางาน 1.2.1 คําสัง่ if ใชทดสอบเพือกํ ่ าหนดเงือนไขการทํ ่ างานของโปรแกรม เชน ถาอินพุตมีคามากกวาคาทีกํ่ าหนด ไวจะใหทําอะไร โดยมีรูปแบบการเขียนดังนี้ if (someVariable > 50) { // do something here }
ตัวโปรแกรม จะทดสอบวาถาตัวแปร someVariable มีคามากกวา 50 หรือไม ถาใชใหทํา อะไร ถาไมใชใหขามการทํางานสวนนี้ การทํางานของคําสั่งนี้จะทดสอบเงื่อนไข ที่เขียนในเครื่องหมายวงเล็บ ถาเงื่อนไขเปนจริง ทําตามคําสั่งที่เขียนในวงเล็บปกกา ถาเงื่อนไขเปนเท็จ ขามการทํางานสวนนีไป ้ สวนของการทดสอบเงื่อนไขที่เขียนอยูภายในวงเล็บ จะตองใชตัวกระทําเปรียบเทียบตางๆ ดังนี้ x == y
(x เทากับ y)
x != y
(x ไมเทากับ y)
x < y
(x นอยกวา y)
x > y
(x มากกวา y)
x <= y
(x นอยกวาหรือเทากับ y)
x >= y
(x มากกวาหรือเทากับ y)
เทคนิคสําหรับการเขียนโปรแกรม ในการเปรียบเทียบตัวแปรใหใชตัวกระทํา == เชน if (x==10) หามเขียนผิดเปน = เชน ่ เขี ่ ยนผิดในแบบนี้ ผลการทดสอบจะเปนจริงเสมอ เมือผ ่ านคําสังนี ่ แล ้ ว x จะมีคาเทา if(x=10) คําสังที กับ 10 ทําใหการทํางานของโปรแกรมผิดเพียนไป ้ ไมเปนตามที่กําหนดไว นอกจากนั้นยังใชคําสั่ง if ควบคุมการแยกเสนทางของโปรแกรม โดยใชคําสั่ง if...else ไดดวย
Arduino IDE 9
1.2.2 คําสัง่
if...else
ใชทดสอบเพื่อกําหนดเงื่อนไขการทํางานของโปรแกรมไดมากกวาคําสั่ง if ธรรมดา โดย สามารถกําหนดไดวา ถาเงือนไขเป ่ นจริงใหทําอะไร ถาเปนเท็จใหทําอะไร เชน ถาคาอินพุตอะนาลอก ที่อานไดนอยกวา 500 ใหทําอะไร ถาคามากกวาหรือเทากับ 500 ใหทําอีกอยาง เขียนคําสั่งไดดังนี้ ตัวอยางที่ 1-3 if (pinFiveInput < 500) { // คําสั่งเพื่อทํางานอยางหนึง่ เนื่องมาจาก pinFiveInput มีคานอยกวา 500 } else { // คําสั่งเพื่อทํางานอีกอยางหนึง่ เนื่องมาจาก pinFiveInput มีคามากวาหรือเทากับ 500 }
หลังคําสัง่ else สามารถตามดวยคําสัง่ if ทําใหรูปแบบคําสังกลายเป ่ น if...else...if เปน การทดสอบเงื่อนไขตางๆ เมื่อเปนจริงใหทําตามที่ตองการ ดังตัวอยางตอไปนี้ ตัวอยางที่ 1-4 if (pinFiveInput < 500) { // คําสั่งเพื่อทํางานอยางหนึง่ เนื่องมาจาก pinFiveInput มีคานอยกวา 500 } else if (pinFiveInput >= 1000) { // คําสั่งเพื่อทํางานอีกอยางหนึง่ เนื่องมาจาก pinFiveInput มีคามากกวาหรือเทากับ 1000 } else { // คําสั่งเพื่อกําหนดใหทํางานตอไปในกรณีที่ pinFiveInput ไมไดมีคานอยกวา 500 // และมากกวาหรือเทากับ 1000 (นั่นคือ จะมีการกระทําคําสั่งในโปรแกรมยอยนีเมื ้ อตั ่ วแปรมีคาอยู // ระหวาง 501 ถึง 999 (ฐานสิบ) }
หลังคําสัง่ else สามารถตามดวยคําสัง่ if ไดไมจํากัด (หรือใชคําสัง่ switch case แทนคําสัง่ if...else...if สําหรับการทดสอบเงือนไขจํ ่ านวนมากๆ ได) เมือใช ่ คําสัง่ if...else แลว ตองกําหนดดวยวา ถาทดสอบไมตรงกับเงือนไขใดๆ ่ เลย ใหทํา อะไร โดยใหกําหนดที่คําสัง่ else ตัวสุดทาย
10 Arduino IDE
1.2.3 คําสัง่
for()
คําสังนี ่ ใช ้ เพือสั ่ งให ่ คําสังที ่ อยู ่ ภายในวงเล็ บปกกาหลัง for มีการทํางานซํากั ้ นตามจํานวนรอบ ทีต่ องการ คําสังนี ่ มี้ ประโยชนมากสําหรับการทํางานใดๆ ทีต่ องทําซํากั ้ นและทราบจํานวนรอบของการ ทําซําที ้ แน ่ นอน มักใชคูกั บตัวแปรอะเรยในการเก็บสะสมคาทีอ่ านไดจากขาอินพุตอะนาลอกหลายๆ ขาที่ มีหมายเลขขาตอเนืองกั ่ น รูปแบบของคําสั่ง for() แบงได 3 สวนดังนี้ for (initialization; condition; increment) { //statement(s); }
เริ่ มต นด วย initialization ใชกําหนดคาเริ่มตนของตัวแปรควบคุมการวนรอบ ในการ ทํางานแตละรอบจะทดสอบ condition ถาเงื่อนไขเปนจริงจะกระทําคําสั่งในวงเล็บปกกา แลวมา เพิ่มหรือลดคาตัวแปรตามที่สั่งใน increment แลวทดสอบเงื่อนไขอีก ทําซํ้าจนกวาเงื่อนไขเปนเท็จ ตัวอยางที่ 1-5 for (int i=1; i <= 8; i++) { // คําสั่งเพื่อทํางานโดยใชคาของตัวแปร i และวนทํางานจนกระทั่งคาของตัวแปร i มากกวา 8; }
คําสั่ง for ของภาษา C จะยืดหยุนกวาคําสั่ง for ของภาษาคอมพิวเตอรอืนๆ ่ โดยสามารถ ละเวนบางสวนหรือทั้งสามสวนของคําสั่ง for ได อยางไรก็ตามยังคงตองมีเซมิโคลอน
Arduino IDE 11
1.2.4 คําสัง่
switch-case
ใชทดสอบเงือนไขเพื ่ ่อกําหนดการทํางานของโปรแกรม ถาตัวแปรทีทดสอบตรงกั ่ บเงื่อนไข ใดก็ใหทํางานตามที่กําหนดไว พารามิเตอร var ตัวแปรทีต่ องการทดสอบวาตรงกับเงือนไขใด ่ default ถาไมตรงกับเงือนไขใดๆ ่ เลยใหทําคําสั่งตอทายนี้ break คําสังหยุ ่ ดการทํางาน ใชเขียนตอทาย case ตางๆ ถาไมไดเขียน โปรแกรมจะวนทํางานตามเงือนไข ่ ตอไปเรือยๆ ่
ตัวอยางที่ 1-6 switch (var) { case 1: // คําสั่งเพื่อทํางาน เมือค ่ าของตัวแปรเทากับ 1 break; case 2: // คําสั่งเพื่อทํางาน เมือค ่ าของตัวแปรเทากับ 2 break; default: // ถาหากคาของตัวแปรไมใช 1 และ 2 ใหกระทําคําสั่งในสวนนี้ }
12 Arduino IDE
1.2.5 คําสัง่ while เปนคําสังวนรอบ ่ โดยจะทําคําสังที ่ เขี ่ ยนในวงเล็บปกกาอยางตอเนือง ่ จนกวาเงือนไขในวงเล็ ่ บ ของคําสัง่ while() จะเปนเท็จ คําสังที ่ ให ่ ทําซําจะต ้ องมีการเปลียนแปลงค ่ าตัวแปรทีใช ่ ทดสอบ เชน มีการเพิมต ่ าตัวแปร หรือมีเงือนไขภายนอกเช ่ นอานคาจากเซ็นเซอรไดเรียบรอยแลวใหหยุดการอานคา มิ ฉะนันเงื ้ อนไขในวงเล็ ่ บของ while() เปนจริงตลอดเวลา ทําใหคําสัง่ while ทํางานวนไมรูจบ รูปแบบคําสั่ง while(expression) { // statement(s); }
พารามิเตอร expression เปนคําสั่งทดสอบเงือนไข ่ (ถูกหรือผิด)
ตัวอยางที่ 1-7 var = 0; while(var < 200) { // คําสั่งเพื่อทํางาน โดยวนทํางานทังสิ ้ ้น 200 รอบ var++; }
Arduino IDE 13
1.3 ตัวกระทําทางคณิตศาสตร ประกอบดวยตัวกระทํา 5 ตัวคือ + (บวก), - (ลบ), * (คูณ), / (หาร) และ % (หารเอาเศษ)
1.3.1 ตัวกระทําทางคณิตศาสตร บวก ลบ คูณ และหาร ใชหาคาผลรวม ผลตาง ผลคูณ และผลหารคาของตัวถูกกระทําสองตัว โดยใหคําตอบมีประเภทตรงกับตัว ถูกกระทําทั้งสองตัว เชน 9/4 ใหคําตอบเทากับ 2 เนืองจากทั ่ ้ง 9 และ 4 เปนตัวแปรเลขจํานวนเต็ม (int) นอกจากนีตั้ วกระทําทางคณิตศาสตรอาจทําใหเกิดโอเวอรโฟลว (overflow) ถาผลลัพธทีได ่ มีขนาดใหญเกิน กวาจะสามารถเก็บในตัวแปรประเภทนัน้ ถาตัวทีถู่ กกระทําตางประเภทกันผลลัพธไดเปนจะมีขนาดใหญขึนเท ้ ากับ ประเภทของตัวแปรทีใหญ ่ ทีสุ่ ด (เชน 9/4 = 2 หรือ 9/3.0 = 2.25)
รูปแบบคําสัง่ result = value1 + value2; result = value1 - value2; result = value1 * value2; result = value1 / value2;
พารามิเตอร value1 : เปนคาของตัวแปรหรือคาคงทีใดๆ ่ value2: เปนคาของตัวแปรหรือคาคงทีใดๆ ่
ตัวอยางที่ 1-8 y = y + 3; x = x - 7; i = j * 6; r = r / 5;
เทคนิคสําหรับการเขียนโปรแกรม เลือกขนาดของตัวแปรใหใหญพอสําหรับเก็บคาผลลัพธที่มากที่สุดของการคํานวณ ่ าใดตัวแปรทีเก็ ่ บจะมีการวนซําค ้ ากลับ และวนกลับอยางไร ตัวอยางเชน ตองทราบวาทีค (0 ไป 1) หรือ (0 ไป -32768) ่ องการเศษสวนใหใชตัวแปรประเภท float แตใหระวังผลลบ เชน สําหรับการคําณวณทีต ตัวแปรมีขนาดใหญ คํานวณไดชา ่ วแปรชัวคราวขณะ ่ ใชตัวกระทํา cast เชน (int)myfloat ในการเปลียนประเภทของตั ทีโปรแกรมทํ ่ างาน
14 Arduino IDE
1.3.2 ตัวกระทํา % หารเอาเศษ ใชหาคาเศษที่ไดของการหารเลขจํานวนเต็ม 2 ตัว ตัวกระทําหารเอาเศษไมสามารถใชงานกับ ตัวแปรเลขทศนิยม (float) รูปแบบคําสัง่ result = value1 % value2;
พารามิเตอร value1 - เปนตัวแปรประเภท byte,char,int หรือ long value2 - เปนตัวแปรประเภท byte,char,int หรือ long
ผลที่ได เศษจากการหารคาเลขจํานวนเต็ม เปนขอมูลชนิดเลขจํานวนเต็ม
ตัวอยางที่ 1-9 x = 7 % 5; x = 9 % 5; x = 5 % 5; x = 4 % 5;
// x now contains 2 // x now contains 4 // x now contains 0 // x now contains 4
ตัวกระทําหารเอาเศษนี้มักนําไปใชในงานที่ตองการใหเหตุการณเกิดขึ้นดวยชวงเวลาที่สมํ่า เสมอ หรือใชทําใหหนวยความทีเก็ ่ บตัวแปรอะเรยเกิดการลนคากลับ (roll over) ตัวอยางที่ 1-10 // ตรวจสอบคาของตัวตรวจจับ 10 ครังต ้ อการทํางาน 1 รอบ void loop() { i++; if ((i % 10) == 0) // หารคาของ i ดวย 10 แลวตรวจสอบเศษการหารเปน 0 หรือไม { x = analogRead(sensPin); // อานคาจากตัวตรวจจับ 10 ครัง้ } } ในตัวอยางนี้เปนการนําคําสั่ง % มาใชกําหนดรอบของการทํางาน โดยโปรแกรมวนทํางานเพืออ ่ านคาจนกวา ผลการหารเอาเศษของคําสั่ง i % 10 จะเทากับ 0 ซึ่งจะเกิดขึ้นเมื่อ i = 10 เทานั้น
Arduino IDE 15
1.4 ตัวกระทําเปรียบเทียบ ใชประกอบกับคําสั่ง if() เพือทดสอบเงื ่ อนไขหรื ่ อเปรียบเทียบคาตัวแปรตาง โดยจะเขียน เปนนิพจนอยูภายในเครื องหมาย ่ () x == y (x เทากับ y) x != y (x ไมเทากับ y) x < y (x นอยกวา y) x > y (x มากกวา y) x <= y (x นอยกวาหรือเทากับ y) x >= y (x มากกวาหรือเทากับ y)
1.5 ตัวกระทําทางตรรกะ ใชในการเปรียบเทียบของคําสั่ง if() มี 3 ตัวคือ &&, || และ !
1.5.1 && (ตรรกะ และ) ใหคาเปนจริงเมื่อผลการเปรียบเทียบทั้งสองขางเปนจริงทั้งคู ตัวอยางที่ 1-11 if (x > 0 && x < 5) { // ... } ใหคาเปนจริงเมือ่ x มากกวา 0 และนอยกวา 5 (มีคา 1 ถึง 4)
1.5.2 && (ตรรกะ หรือ) ใหคาเปนจริง เมื่อผลการเปรียบเทียบพบวา มีตัวแปรตัวใดตัวหนึ่งเปนจริงหรือเปนจริงทั้งคู ตัวอยางที่ 1-12 if (x > 0 || y > 0) { // ... } ใหผลเปนจริงเมือ่ x หรือ y มีคามากกวา 0
16 Arduino IDE
1.5.3 ! (ใชกลับผลเปนตรงกันขาม) ใหคาเปนจริง เมื่อผลการเปรียบเทียบเปนเท็จ ตัวอยางที่ 1-13 if (!x) { // ... } ใหผลเปนจริงถา x เปนเท็จ (เชน ถา x = 0 ใหผลเปนจริง)
1.5.4 ขอควรระวัง ระวังเรื่องการเขียนโปรแกรม ถาตองการใชตัวกระทําตรรกะและ ตองเขียนเครื่องหมาย && ถาลืมเขียนเปน & จะเปนตัวกระทําและระดับบิตกับตัวแปร ซึ่งใหผลที่แตกตาง เชนกันในการใชตรรกะหรือใหเขียนเปน || (ขีดตั้งสองตัวติดกัน) ถาเขียนเปน | (ขีดตั้งตัว เดียว) จะหมายถึงตัวกระทําหรือระดับบิตกับตัวแปร ตัวกระทํา NOT ระดับบิต (~) จะแตกตางจากตัวกลับผลใหเปนตรงขาม (!) ตองเลือกใชให ถูกตอง ตัวอยางที่ 1-14 if (a >= 10 && a <= 20){} // ใหผลการทํางานเปนจริงเมือ่ a มีคาอยูระหวาง 10 ถึง 20
Arduino IDE 17
1.6 ตัวกระทําระดับบิต ตัวกระทําระดับจะนําบิตของตัวแปรมาประมวลผล ใชประโยชนในการแกปญหาดานการ เขียนโปรแกรมไดหลากหลาย ตัวกระทําระดับของภาษาซี (ซึ่งรวมถึง Arduino) มี 6 ตัวไดแก & (bitwise AND), | (OR), ^ (Exclusive OR), ~ (NOT), << (เลือนบิ ่ ตไปทางขวา) และ >> (เลือนบิ ่ ตไป ทางซาย)
1.6.1 ตัวกระทําระดับบิต AND (&) คําสั่ง AND ในระดับบิตของภาษาซีเขียนไดโดยใช & หนึงตั ่ ว โดยตองเขียนระหวางนิพจน หรือตัวแปรทีเป ่ นเลขจํานวนเต็ม การทํางานจะนําขอมูลแตละบิตของตัวแปรทังสองตั ้ วมากระทําทาง ตรรกะ AND โดยมีกฎดังนี้ ถาอินพุตทั้งสองตัวเปน “1” ทั้งคูเอาตพุตเปน “1” กรณีอืนๆ ่ เอาตพุตเปน “0” ดังตัวอยางตอ ไปนี้ ในการดูใหคูของตัวกระทําตามแนวตั้ง 0 0 1 1 0 1 0 1 —————————— 0 0 0 1
Operand1 Operand2 Returned result
ใน Arduino ตัวแปรประเภท int จะมีขนาด 16 บิต ดังนั้นเมื่อใชตัวกระทําระดับบิต AND จะมี การกระทําตรรกะและพรอมกันกับขอมูลทั้ง 16 บิต ดังตัวอยางในสวนของโปรแกรมตอไปนี้ ตัวอยางที่ 1-15 int a = 92; // เทากับ 0000000001011100 ฐานสอง int b = 101; // เทากับ 0000000001100101 ฐานสอง int c = a & b; // ผลลัพธคือ 0000000001000100 ฐานสองหรือ 68 ฐานสิบ ในตัวอยางนี้จะนําขอมูลทัง้ 16 บิตของตัวแปร a และ b มากระทําทางตรรกะ AND แลวนําผลลัพธทีได ่ ทัง้ 16 บิตไปเก็บที่ตัวแปร c ซึ่งไดคาเปน 01000100 ในเลขฐานสองหรือเทากับ 68 ฐานสิบ
นิยมใชตัวกระทําระดับบิต AND เพือใช ่ เลือกขอมูลบิตที่ตองการ (อาจเปนหนึงบิ ่ ตหรือหลาย บิต) จากตัวแปร int ซึ่งการเลือกเพียงบางบิตนี้จะเรียกวา masking
18 Arduino IDE
1.6.2 ตัวกระทําระดับบิต OR (|) คําสั่งระดับบิต OR ของภาษาซีเขียนไดโดยใชเครื่องหมาย |หนึ่งตัว โดยตองเขียนระหวาง นิพจนหรือตัวแปรที่เปนเลขจํานวนเต็ม สําหรับการทํางานใหนําขอมูลแตละบิตของตัวแปรทั้งสอง ตัวมากระทําทางตรรกะ OR โดยมีกฎดังนี้ ถาอินพุตตัวใดตัวหนึงหรื ่ อทังสองตั ้ วเปน “1” เอาตพุตเปน “1” กรณีทีอิ่ นพุตเปน “0” ทังคู ้ เอาตพุต จึงจะเปน “0” ดังตัวอยางตอไปนี้ 0 0 1 1 0 1 0 1 —————————— 0 1 1 1
Operand1 Operand2 Returned result
ตัวอยางที่ 1-16 สวนของโปรแกรมแสดงการใชตัวกระทําระดับบิต OR int a = 92; // เทากับ 0000000001011100 ฐานสอง int b = 101; // เทากับ 0000000001100101 ฐานสอง int c = a | b; // ผลลัพธคือ 0000000001111101 ฐานสอง หรือ 125 ฐานสิบ
ตัวอยางที่ 1-17 โปรแกรมแสดงการใชตัวกระทําระดับบิต AND และ OR ตัวอยางงานทีใช ่ ตัวกระทําระดับบิต AND และ OR เปนงานที่โปรแกรมเมอรเรียกวา Read-Modify-Write on a port สําหรับไมโครคอนโทรลเลอร 8 บิต คาที่อานหรือเขียนไปยังพอรตมีขนาด 8 บิต ซึ่งแสดงคาอินพุตทีขาทั ่ ง้ 8 ขา การเขียนคาไปยังพอรตจะเขียนคาครังเดี ้ ยวไดทัง้ 8 บิต ตัวแปรชื่อ PORTD เปนคาที่ใชแทนสถานะของขาดิจิตอลหมายเลข 0,1,2,3,4,5,6,7 ถาบิตใดมีคาเปน 1 ทําใหขานันมี ้ คาลอจิกเปน HIGH (อยาลืมกําหนดใหขาพอรตนันๆ ้ ทํางานเปนเอาตพุตดวยคําสัง่ pinMode() กอน) ดังนัน้ ถากําหนดคาให PORTD = B00110001; ก็คือตองการใหขา 2,3 และ 7 เปน HIGH ในกรณีนี้ไมตองเปลียนค ่ า สถานะของขา 0 และ 1 ซึงปกติ ่ แลวฮารดแวรของ Arduino ใชในการสือสารแบบอนุ ่ กรม ถาไปเปลียนค ่ าแลวจะกระทบ ตอการสื่อสารแบบอนุกรม อัลกอริธึมสําหรับโปรแกรมเปนดังนี้ ่ องการควบคุม (ใชตัวกระทําแบบบิต AND) อานคาจาก PORTD แลวลางคาเฉพาะบิตทีต นําคา PORTD ทีแก ่ ไขจากขางตนมารวมกับคาบิตทีต่ องการควบคุม (ใชตัวกระทําแบบบิต OR) เขียนเปนโปรแกรมไดดังนี้
Arduino IDE 19
int i; // counter variable int j; void setup() { DDRD = DDRD | B11111100; // กําหนดทิศทางของขาพอรต 2 ถึง 7 ดวยคา 11111100 Serial.begin(9600); } void loop() { for (i=0; i<64; i++) { PORTD = PORTD & B00000011; // กําหนดขอมูลไปยังขาพอรต 2 ถึง 7 j = (i << 2); PORTD = PORTD | j; Serial.println(PORTD, BIN); // แสดงคาของ PORTD ทีหน ่ าตาง Serial montior delay(100); } }
1.6.3 คําสังระดั ่ บบิต Exclusive OR (^) เปนโอเปอรเตอรพิเศษทีไม ่ คอยไดใชในภาษา C/C++ ตัวกระทําระดับบิต exclusive OR (หรือ XOR) จะเขียนโดยใชสัญลักษณเครื่องหมาย ^ ตัวกระทํานี้มีการทํางานใกลเคียงกับตัวกระทําระดับ บิต OR แตตางกันเมื่ออินพุตเปน “1” ทั้งคูจะใหเอาตพุตเปน “0” แสดงการทํางานไดดังนี้ 0 0 1 1 0 1 0 1 —————————— 0 1 1 0
Operand1 Operand2 Returned result
หรือกลาวไดอีกอยางวา ตัวกระทําระดับบิต XOR จะใหเอาตพุตเปน “0” เมื่ออินพุตทั้งสอง ตัวมีคาเหมือนกัน และใหเอาตพุตเปน “1” เมื่ออินพุตทั้งสองมีคาตางกัน ตัวอยางที่ 1-18 int x = 12; int y = 10; int z = x ^ y;
// คาเลขฐานสองเทากับ 1100 // คาเลขฐานสองเทากับ 1010 // ผลลัพธเทากับ 0110 ฐานสองหรือ 6 ฐานสิบ
ตัวกระทําระดับบิต XOR จะใชมากในการสลับคาบางบิตของตัวตัวแปร int เชน กลับจาก “0” เปน “1” หรือกลับจาก “1” เปน “0” เมื่อใชตัวกระทําระดับบิต XOR ถาบิตของ mask เปน “1” ทําใหบิตนั้นถูกสลับคา ถา mask มีคาเปน “1” บิตนั้นมีคาคงเดิม ตัวอยางตอไปนี้เปนโปรแกรมแสดงการสั่งใหขาดิจิตอล 5 มีการกลับ ลอจิกตลอดเวลา
20 Arduino IDE
ตัวอยางที่ 1-19 void setup() { DDRD = DDRD | B00100000; } void loop() { PORTD = PORTD ^ B00100000; delay(100); }
// กําหนดขา 5 เปนเอาตพุต // กลับลอจิกทีขา ่ 5
1.6.4 ตัวกระทําระดับบิต NOT (~) ตัวกระทําระดับบิต NOT จะเขียนโดยใชสัญลักษณเครื่องหมาย ~ ตัวกระทํานี้จะใชงานกับ ตัวถูกกระทําเพียงตัวเดียวทีอยู ่ ขวามื อ โดยทําการสลับบิตทุกบิตใหมีคาตรงกันขามคือ จาก “0” เปน “1” และจาก “1” เปน “0” ดังตัวอยาง 0 1 ————— 1 0
Operand1 ~ Operand1
int a = 103; int b = ~a;
// binary: 0000000001100111 // binary: 1111111110011000
เมือกระทํ ่ าแลว ทําใหตัวแปร b มีคา -104 (ฐานสิบ) ซึงคํ ่ าตอบทีได ่ ติดลบเนืองจากบิ ่ ตทีมี่ ความ สําคัญสูงสุด (บิตซายมือสุด) ของตัวแปร int อันเปนบิตแจงวาตัวเลขเปนบวกหรือลบ มีคาเปน “1” แสดงวา คาทีได ่ นีติ้ ดลบ โดยในคอมพิวเตอรจะเก็บคาตัวเลขทังบวกและลบตามระบบทู ้ คอมพลีเมนต (2’s complement) การประกาศตัวแปร int ซึงมี ่ ความหมายเหมือนกับการประกาศตัวแปรเปน signed int ตองระวัง คาของตัวแปรจะติดลบได
Arduino IDE 21
1.6.5 คําสังเลื ่ อนบิ ่ ตไปทางซาย (<<) และเลือนบิ ่ ตไปทางขวา (>>) ในภาษา C/C++ มีตัวกระทําเลื่อนบิตไปทางซาย << และเลื่อนบิตไปทางขวา >> ตัวกระทํา นี้จะสั่งเลือนบิ ่ ตของตัวถูกกระทําทีเขี ่ ยนดานซายมือไปทางซายหรือไปทางขวาตามจํานวนบิตที่ระบุ ไวในดานขวามือของตัวกระทํา รูปแบบคําสัง่ variable << number_of_bits variable >> number_of_bits
พารามิเตอร variable เปนตัวแปรเลขจํานวนเต็มที่มีจํานวนบิตนอยกวาหรือเทากับ 32 บิต (หรือตัวแปรประเภท byte, int หรือ long)
ตัวอยางที่ 1-20 int a = 5; int b = a << 3; int c = b >> 3;
// เทากับ 0000000000000101 ฐานสอง // ไดผลลัพธเปน 0000000000101000 ฐานสองหรือ 40 // ไดผลลัพธเปน 0000000000000101 ฐานสองหรือ 5 ฐานสิบ
ตัวอยางที่ 1-21 เมื่อสั่งเลื่อนคาตัวแปร x ไปทางซายจํานวน y บิต (x << y) บิตขอมูลที่อยูดานซายสุดของ x จํานวน y ตัวจะหายไปเนื่องจากถูกเลื่อนหายไปทางซายมือ int a = 5; // เทากับ 0000000000000101ฐานสอง int b = a << 14; // ไดผลลัพธเปน 0100000000000000 ฐานสอง
การเลื่อนบิตไปทางซาย จะทําใหคาของตัวแปรดานซายมือของตัวกระทําจะถูกคูณดวยคา สองยกกําลังบิตที่เลื่อนไปทางซายมือ ดังนี้ 1 << 0 1 << 1 1 << 2 1 << 3 ... 1 << 8 1 << 9 1 << 10 ...
== == == ==
1 2 4 8
== 256 == 512 == 1024
22 Arduino IDE
เมือสั ่ งเลื ่ อนตั ่ วแปร x ไปทางขวามือจํานวน y บิต (x >> y) จะมีผลแตกตางกันขึนกั ้ บประเภท ของตัวแปร ถา x เปนตัวแปรประเภท int คาทีเก็ ่ บไดมีทังค ้ าบวกและลบ โดยบิตซายมือสุดจะเปน sign bit หรือบิตเครืองหมาย ่ ถาเปนคาลบ คาบิตซายมือสุดจะมีคาเปน 1 กรณีนีเมื ้ อสั ่ งเลื ่ อนบิ ่ ตไปทางขวามือ แลว โปรแกรมจะนําคาของบิตเครืองหมายมาเติ ่ มใหกับบิตทางซายมือสุด ปรากฏการณนีเรี้ ยกวา sign extension มีตัวอยางดังนี้ ตัวอยางที่ 1-22 int x = -16; int y = x >> 3;
// เทากับ 1111111111110000 ฐานสอง // เลือนบิ ่ ตของตัวแปร x ไปทางขวา 3 ครัง้ // ไดผลลัพธเปน 1111111111111110 ฐานสอง
ถาตองการเลือนบิ ่ ตไปทางขวามือแลวใหคา 0 มาเติมยังบิตซายมือสุด (ซึงเกิ ่ ดกับกรณีทีตั่ วแปร เปนประเภท unsigned int) ทําไดโดยใชการเปลี่ยนประเภทตัวแปรชัวคราว ่ (typecast) เพือเปลี ่ ยนให ่ ตัวแปร x เปน unsigned int ชั่วคราวดังตัวอยางตอไปนี้ ตัวอยางที่ 1-23 int x = -16; // เทากับ 1111111111110000 ฐานสอง int y = unsigned(x) >> 3; // เลือนบิ ่ ตของตัวแปร x (แบบไมคิดเครืองหมาย) ่ ไปทางขวา 3 ครัง้ // ไดผลลัพธเปน 0001111111111110 ฐานสอง
ถาหากระมัดระวังเรื่อง sign extension แลว ก็จะใชตัวกระทําเลื่อนบิตไปทางขวามือสําหรับ หารคาตัวแปรดวย 2 ยกกําลังตางๆ ไดดังตัวอยาง ตัวอยางที่ 1-24 int x = 1000; int y = x >> 3;
// หารคาของ 1000 ดวย 8 (มาจาก 23) ทําให y = 125
Arduino IDE 23
1.7 ไวยากรณภาษาของ Arduino 1.7.1 ; (เซมิโคลอน - semicolon) ใชเขียนแจงวา จบคําสั่ง ตัวอยางที่ 1-25 int a = 13;
บรรทัดคําสั่งที่ลืมเขียนปดทายดวยเซมิโคลอน จะทําใหแปลโปรแกรมไมผาน โดยตัวแปร ภาษาอาจจะแจงใหทราบวา ไมพบเครืองหมายเซมิ ่ โคลอน หรือแจงเปนการผิดพลาดอื่นๆ บางกรณี ที่ตรวจสอบบรรทัดที่แจงวาเกิดการผิดพลาดแลวไมพบที่ผิด ใหตรวจสอบบรรทัดกอนหนานั้น
1.7.2 { } (วงเล็บปกกา - curly brace) เครื่องหมายวงเล็บปกกา เปนสวนสําคัญของภาษาซี ใชในการกําหนดขอบเขตการทํางานใน แตละชวง วงเล็บปกกาเปด { จะตองเขียนตามดวยวงเล็บปกกาปด } ดวยเสมอ หรือเรียกวา วงเล็บตอง ครบคู ในซอฟตแวร Arduino IDE ที่ใชเขียนโปรแกรมจะมีความสามารถในการตรวจสอบการครบ คูของเครื่องหมายวงเล็บ ผูใชงานเพียงแคคลิกที่วงเล็บ มันจะแสดงวงเล็บที่เหลือซึงเป ่ นคูของมัน สําหรับโปรแกรมเมอรมือใหมและโปรแกรมเมอรที่ยายจากภาษา BASIC มาเปนภาษา C มัก จะสับสนกับการใชเครืองหมายวงเล็ ่ บ แททีจริ ่ งแลวเครืองหมายป ่ กกาปดนีเที ้ ยบไดกับคําสัง่ RETURN ของ subroutine (function) หรือแทนคําสั่ง ENDIF ในการเปรียบเทียบ และแทนคําสั่ง NEXT ของคํา สั่งวนรอบ FOR เนืองจากมี ่ การใชวงเล็บปกกาไดหลากหลาย ดังนันเมื ้ อต ่ องการเขียนคําสังที ่ ต่ องใชเครืองหมาย ่ วงเล็บ เมื่อเขียนวงเล็บเปดแลวใหเขียนเครื่องหมายวงเล็บปดทันที ถัดมาจึงคอยเคาะปุม Enter ใน ระหวางเครืองหมายวงเล็ ่ บเพือขึ ่ นบรรทั ้ ดใหม แลวเขียนคําสังที ่ ต่ องการ ถาทําไดตามนีวงเล็ ้ บจะครบ คูแนนอน สําหรับวงเล็บทีไม ่ ครบคู ทําใหเกิดความผิดพลาดในขณะคอมไพลโปรแกรม ถาเปนโปรแกรม ขนาดใหญจะหาที่ผิดไดยาก ตําแหนงที่อยูของเครื่องหมายวงเล็บแตละตัวจะมีผลอยางมากตอ ไวยากรณของภาษาคอมพิวเตอร การยายตําแหนงวงเล็บไปเพียงหนึ่งหรือสองบรรทัด ทําใหตัว โปรแกรมทํางานผิดไป
24 Arduino IDE
ตําแหนงที่ใชวงเล็บปกกา ฟงกชั่น (Function) void myfunction(datatype argument) { statements(s) }
คําสังวนรอบ ่ (Loops) while (boolean expression) { statement(s) } do { statement(s) } while (boolean expression); for (initialisation; termination condition; incrementing expr) { statement(s) }
คําสังทดสอบเงื ่ อนไข ่ (condition) if (boolean expression) { statement(s) } else if (boolean expression) { statement(s) } else { statement(s) }
1.7.3
// และ /*...*
หมายเหตุบรรทัดเดียวและหลายบรรทัด
เปนสวนของโปรแกรมทีผู่ ใช เขียนเพิมเติ ่ มวาโปรแกรมทํางานอยางไร โดยสวนทีเป ่ นหมายเหตุ จะไมถูกคอมไพล ไมนําไปประมวลผล มีประโยชนมากสําหรับการตรวจสอบโปรแกรมภายหลังหรือ ใชแจงใหเพือนร ่ วมงานหรือบุคคลอืนทราบว ่ าบรรทัดนีใช ้ ทําอะไร ตัวหมายเหตุภาษาซีมี 2 ประเภทคือ (1) หมายเหตุบรรรทัดเดียว เขียนเครื่องสแลช // 2 ตัวหนาบรรทัด (2) หมายเหตุหลายบรรทัด เขียนเครืองหมายสแลช ่ บดอกจัน * ครอมขอความทีเป ่ น / คูกั หมายเหตุ เชน /* blabla */
Arduino IDE 25
1.7.4 #define เปนคําสั่งที่ใชงานมากในการกําหนดคาคงที่ใหกับโปรแกรม เนื่องจากเปนการกําหนดคาที่ ไมใชพืนที ้ หน ่ วยความจําของไมโครคอนโทรลเลอรแตอยางใด เมือถึ ่ งขันตอนแปลภาษา ้ คอมไพเลอร จะแทนที่ตัวอักษรดวยคาที่กําหนดไว ใน Arduino จะใช คําสั่ง #define ตรงกับภาษา C รูปแบบ #define constantName value
อยาลืมเครื่องหมาย # ตัวอยางที่ 1-26 #define ledPin 3
// เปนการกําหนดใหตัวแปร ledPin เทากับคาคงที่ 3
ทายคําสัง่ #define ไมตองมีเครื่องหมายเซมิโคลอน
1.7.5 #include ใชสั่งใหรวมไฟลอืนๆ ่ เขากับไฟลโปรแกรมของเรากอน แลวจึงทําการคอมไพลโปรแกรม รูปแบบคําสัง่ #include <file> #include “file”
ตัวอยางที่ 1-27 #include <stdio.h> #include “popx2.h”
บรรทัดแรกจะสั่งใหเรียกไฟล stdio.h มารวมกับไฟลโปรแกรมที่กําลังพัฒนา โดยคนหาไฟล จากตําแหนงที่เก็บไฟลระบบของ Arduino โดยปกติเปนไฟลมาตรฐานที่มาพรอมกับ Arduino บรรทัดที่ 2 สั่งใหรวมไฟล popx2.h มารวมกับไฟลโปรแกรมที่กําลังพัฒนา โดยหาไฟลจาก โฟลเดอรที่อยูของไฟลภาษา C กอน ปกติเปนไฟลที่ผูใช สรางขึนเอง ้
26 Arduino IDE
1.8 ตัวแปร ตัวแปรเปนตัวอักษรหลายตัวๆ ทีกํ่ าหนดขึนในโปรแกรมเพื ้ อใช ่ ในการเก็บคาขอมูลตางๆ เชน คาที่อานไดจากตัวตรวจจับที่ตออยูกับขาพอรตอะนาลอกของ Arduino ตัวแปรมีหลายประเภทดังนี้
1.8.1 char : ตัวแปรประเภทตัวอักขระ เปนตัวแปรทีมี่ ขนาด 1 ไบต (8 บิต) มีไวเพือเก็ ่ บคาตัวอักษร ตัวอักษรในภาษา C จะเขียนอ ยูในเครื่องหมายคําพูดขีดเดียว เชน ‘A’ (สําหรับขอความ ที่ประกอบจากตัวอักษรหลายตัวเขียนตอ กันจะเขียนอยูในเครื่องหมายคําพูดปกติ เชน “ABC”) คุณสามารถสั่งกระทําทางคณิตศาสตรกับตัว อักษรได ในกรณีจะนําคารหัส ASCII ของตัวอักษรมาใช เชน ‘A’ +1 มีคาเทากับ 66 เนื่องจากคา รหัส ASCII ของตัวอักษร A เทากับ 65 รูปแบบคําสัง่ char sign = ' ';
ตัวอยางที่ 1-28 char var = 'x'; var คือชื่อของตัวแปรประเภท char ทีต่ องการ x คือคาทีต่ องการกําหนดใหกับตัวแปร ในที่นีเป ้ นตัวอักษรหนึ่งตัว
1.8.2 byte : ตัวแปรประเภทตัวเลข 8 บิตหรือ 1 ไบต ตัวแปร byte ใชเก็บคาตัวเลขขนาด 8 บิต มีคาไดจาก 0 - 255 ตัวอยางที่ 1-29 byte b = B10010; // แสดงคาของ b ในรูปของเลขฐานสอง (เทากับ 18 เลขฐานสิบ)
1.8.3 int : ตัวแปรประเภทตัวเลขจํานวนเต็ม ยอจาก interger ซึ่งแปลวาเลขจํานวนเต็ม int เปนตัวแปรพื้นฐานสําหรับเก็บตัวเลข ตัวแปร หนึ่งตัวมีขนาด 2 ไบต เก็บคาไดจาก -32,768 ถึง 32,767 ซึ่งมาจาก -215 (คาตํ่าสุด) และ 215- 1 (คาสูง สุด) ในการเก็บคาตัวเลขติดลบใชเทคนิคที่เรียกวา ทูคอมพลีเมนต (2’s complement) บิตสูงสุดบาง ครั้งเรียกวา บิตเครื่องหมาย หรือ sign bit ถามีคาเปน “1” แสดงวา เปนคาติดลบ รูปแบบคําสัง่ int var = val;
พารามิเตอร var คือชื่อของตัวแปรประเภท int ทีต่ องการ val คือคาที่ตองการกําหนดใหกับตัวแปร
Arduino IDE 27
ตัวอยางที่ 1-30 int ledPin = 13;
// กําหนดใหตัวแปร ledPIn มีคาเทากับ 13
เมื่อตัวแปรมีคามากกวาคาสูงสุดที่เก็บได จะเกิดการ “ลนกลับ” (roll over) ไปยังคาตํ่าสุดที่ เก็บได และเมื่อมีคานอยกวาคาตํ่าสุดที่เก็บไดจะลนกลับไปยังคาสูงสุด ดังตัวอยางตอไปนี้ ตัวอยางที่ 1-31 int x x = -32,768; x = x - 1; x = 32,767; x = x + 1;
// เมื่อกระทําคําสั่งแลว คาของ x จะเปลียนจาก ่ -32,768 เปน 32,767 // เมื่อกระทําคําสั่งแลว คาของ x จะเปลียนจาก ่ 32,767 เปน -32,768
1.8.4 unsigned int : ตัวแปรประเภทเลขจํานวนเต็มไมคิดเครืองหมาย ่ ตัวแปรประเภทนี้คลายกับตัวแปร int แตจะเก็บเลขจํานวนเต็มบวกเทานั้น โดยเก็บคา 0 ถึง 65,535 (216 -1) รูปแบบคําสัง่ unsigned int var = val;
พารามิเตอร var คือชื่อของตัวแปร int ทีต่ องการ val คือคาที่ตองการกําหนดใหกับตัวแปร
ตัวอยางที่ 1-32 unsigned int ledPin = 13; // กําหนดใหตัวแปร ledPIn มีคาเทากับ 13 แบบไมคิดเครืองหมาย ่
เมื่อตัวแปรมีคาสูงสุดจะลนกลับไปคาตํ่าสุดหากมีการเพิ่มคาตอไป และเมื่อมีคาตํ่าสุดจะลน กลับเปนคาสูงสุดเมื่อมีการลดคาตอไปอีก ดังตัวอยาง ตัวอยางที่ 1-33 unsigned int x x = 0; x = x - 1; // เมือกระทํ ่ าคําสั่งแลว คาของ x จะเปลียนจาก ่ 0 เปน 65535 x = x + 1; // เมือกระทํ ่ าคําสั่งแลว คาของ x จะเปลียนจาก ่ 65535 กลับไปเปน 0
28 Arduino IDE
1.8.5 long : ตัวแปรประเภทเลขจํานวนเต็ม 32 บิต เปนตัวแปรเก็บคาเลขจํานวนเต็มที่ขยายความจุเพิมจากตั ่ วแปร int โดยตัวแปร long หนึงตั ่ ว กินพืนที ้ ่หนวยความจํา 32 บิต (4 ไบต) เก็บคาไดจาก -2,147,483,648 ถึง 2,147,483,647 รูปแบบคําสัง่ long var = val;
พารามิเตอร var คือชื่อของตัวแปร long ทีต่ องการ val คือคาที่ตองการกําหนดใหกับตัวแปร
ตัวอยางที่ 1-34 long time;
// กําหนดใหตัวแปร time เปนแบบ long
1.8.6 unsigned long : ตัวแปรประเภทเลขจํานวนเต็ม 32 บิต แบบไมคิดเครืองหมาย ่ เปนตัวแปรเก็บคาเลขจํานวนเต็มบวก ตัวแปรหนึงตั ่ วกินพืนที ้ ่หนวยความจํา 32 บิต (4 ไบต) เก็บคาไดจาก 0 ถึง 4,294,967,295 หรือ 232 -1 รูปแบบคําสัง่ unsigned long var = val;
พารามิเตอร var คือชื่อของตัวแปร unsigned long ทีต่ องการ val คือคาที่ตองการกําหนดใหกับตัวแปร
ตัวอยางที่ 1-35 unsigned long time;
// กําหนดใหตัวแปร time เปนแบบ undigned long (ไมคิดเครืองหมาย) ่
Arduino IDE 29
1.8.7 float : ตัวแปรประเภทเลขทศนิยม เปนตัวแปรสําหรับเก็บคาเลขเลขทศนิยม ซึ่งนิยมใชในการเก็บคาสัญญาณอะนาล็อกหรือคา ที่ตอเนื่อง เนื่องจากสามารถเก็บคาไดละเอียดกวาตัวแปร int ตัวแปร float เก็บคาไดจาก -4.4028235 x 1038 ถึง 4.4028235 x 1038 โดยหนึงตั ่ วจะกินพืนที ้ ่หนวยความจํา 32 บิต (4 ไบต) ในการคํานวณคณิตศาสตรกับตัวแปร float จะชากวาการคํานวณของตัวแปร int ดังนั้นจึง พยายามหลีกเลียงการคํ ่ านวณกับตัวแปร float ในกรณีกระทําคําสังวนรอบที ่ ต่ องทํางานดวยความเร็ว สูงสุดของฟงกชั่นทางเวลาที่ตองแมนยําอยางมาก โปรแกรมเมอรบางคนจะทําการแปลงตัวเลข ทศนิยมใหเปนเลขจํานวนเต็มกอนแลวจึงคํานวณเพื่อใหทํางานไดเร็วขึน้ รูปแบบคําสั่ง float var = val;
พารามิเตอร var คือชื่อของตัวแปร float ทีต่ องการ val คือคาที่ตองการกําหนดใหกับตัวแปร
ตัวอยางที่ 1-36 float myfloat; float sensorCalbrate = 1.117;
ตัวอยางที่ 1-37 int x; int y; float z; x = 1; y = x / 2; // y เทากับ 0 ไมมีการเก็บคาของเศษที่ไดจากการหาร z = (float)x / 2.0; // z เทากับ 0.5 เมือมี ่ การใชตัวแปรแบบ float ตัวเลขทีนํ่ ามากระทํากับตัวแปรแบบ float นีจะต ้ องเปนเลขทศนิยมดวย จากตัวอยางคือ เลข 2 เมือนํ ่ ามาทํางานกับตัวแปร x ทีเป ่ นแบบ float เลข 2 จึงตองเขียนเปน 2.0
1.8.8 double : ตัวแปรประเภทเลขทศนิยมความละเอียดสองเทา เปนตัวแปรทศนิยมความละเอียดสองเทา มีขนาด 8 ไบต คาสูงสุดทีเก็่ บไดคือ 1.7976931348623157 x 10308 ใน Arduino มีหนวยความจําจํากัด จึงไมใชตัวแปรประเภทนี้
30 Arduino IDE
MicroBOX-Note
การกําหนดคาคงทีเลขจํ ่ านวนเต็มเปนเลขฐานตางๆ ของ Arduino คาคงที่เลขจํานวนเต็มก็คือตัวเลขทีคุ่ ณเขียนในโปรแกรมของ Arduino โดยตรงเชน 123 โดยปกติแลว ตัวเลขเหลานีจะเป ้ นเลขฐานสิบ (decimal) ถาตองการกําหนดเปนเลขฐานอืนจะต ่ องใชเครืองหมายพิ ่ เศษระบ เชุ น ฐาน ตัวอยาง 10 (decimal) 123 2 (binary) B1111011 8 (octal) 0173 16 (hexadecimal) 0x7B Decimal ก็คือเลขฐานสิบ ซึ่งใชในชีวิตประจําวัน ตัวอยาง 101 = 101 มาจาก (1* 102) + (0 * 101) + (1 * 100) = 100 + 0 + 1 = 101 Binary เปนเลขฐานสอง ตัวเลขแตละหลักเปนไดแค 0 หรือ 1 ตัวอยาง B101 = 5 ฐานสิบ มาจาก (1 * 22) + (0 * 21) + (1 * 20) = 4 + 0 + 1 = 5 เลขฐานสองจะใชงานไดไมเกิน 8 บิต (ไมเกิน 1 ไบต) มีคาจาก 0 (B0) ถึง 255 (B11111111) Octal เปนเลขฐานแปด ตัวเลขแตละหลักมีคาจาก 0 ถึง 7 เทานั้น ตัวอยาง 0101 = 65 ฐานสิบ มาจาก (1 * 82) + (0 * 81) + (1 * 80) = 64 + 0 +1 = 65 ขอควรระวังในการกําหนดคาคงที่ อยาเผลอใสเลข 0 นําหนา มิฉะนันตั ้ วคอมไพเลอรจะแปลความหมาย ผิดไปวาคาตัวเลขเปนเลขฐาน 8 Hexadecimal (hex) เปนเลขฐานสิบหก ตัวเลขแตละหลักมีคาจาก 0 ถึง 9 และตัวอักษร A คือ 10, B คือ 11 ไปจนถึง F ซึ่งเทากับ 15 ตัวอยาง 0x101 = 257 ฐานสิบ มาจาก (1 * 162) + (0 * 161) + (1 * 160) = 256 + 0 + 1 = 257
Arduino IDE 31
1.8.9 string : ตัวแปรประเภทขอความ เปนตัวแปรเก็บขอความ ซึ่งในภาษาซีจะนิยามเปนอะเรยของตัวแปรประเภท char ตัวอยางที่ 1-38 ตัวอยางการประกาศตัวแปรสตริง char Str1[15]; char Str2[8] = {'a','r','d','u','i','n','o'}; char Str3[8] = {'a','r','d','u','i','n','o','\0'}; char Str4[ ] = "arduino"; char Str5[8] = "arduino"; char Str6[15] = "arduino"; Str1 เปนการประกาศตัวแปรสตริงโดยไมไดกําหนดคาเริมต ่ น ่ Str2 ประกาศตัวแปรสตริงพรอมกําหนดคาใหกับขอความทีละตัวอักษร หากไมครบตามจํานวนทีประกาศ คอมไพเลอรจะเพิ่ม null string ใหเองจนครบ (จากตัวอยางประกาศไว 8 ตัว แตขอความมี 7 ตัวอักษร จึงมีการเติม null string ใหอีก 1 ตัว Str3 ประกาศตัวแปรสตริงพรอมกําหนดคาใหกับขอความ แลวปดทายดวยตัวอักษรปด นั่นคือ \0 Str4 ประกาศตัวแปรสตริงพรอมกําหนคคาตัวแปรในเครืองหมายคํ ่ าพูด จากตัวอยาง ไมไดกําหนดขนาด ตัวแปร คอมไพเลอรจะกําหนดขนาดใหเองตามจํานวนตัวอักษร ่ าพูด และขนาดของตัวแปร จากตัวอยาง Str5 ประกาศตัวแปรสตริงพรอมกําหนคคาตัวแปรในเครืองหมายคํ ประกาศไว 8 ตัว ่ ่ยาวมากกวานี้ Str6 ประกาศตัวแปรสตริง โดยกําหนดขนาดเผื่อไวสําหรับขอความอืนที
1.8.9.1 การเพิ่มตัวอักษรแจงวาจบขอความ (null termination) ในตัวแปรสตริงของภาษา C กําหนดใหตัวอักษรสุดทายเปนตัวแจงการจบขอความ (null string) ซึงก็ ่ คือตัวอักษร \0 ในการกําหนดขนาดของตัวแปร (คาในวงเล็บเหลียม) ่ จะตองกําหนดใหเทากับ จํานวนตัวอักษร + 1 ดังในตัวแปร Str2 และ Str3 ในตัวอยางที่ 1-38 ทีข่ อความ Arduino มีตัวอักษร 7 ตัว ในการประกาศตัวแปรตองระบุเปน [8] ในการประกาศตัวแปรสตริง ตองเผื่อพื้นที่สําหรับเก็บตัวอักษรแจงวาจบขอความ มิฉะนั้น คอมไพเลอรจะแจงเตือนวาเกิดการผิดพลาด ในตัวอยางที่ 1-38 ตัวแปร Str1 และ Str6 เก็บขอความ ไดสูงสุด 14 ตัวอักษร
1.8.9.2 เครื่องหมายคําพูดขีดเดียวและสองขีด ปกติแลวจะกําหนดคาตัวแปรสตริงภายในเครืองหมายคํ ่ าพูด เชน "Abc" สําหรับตัวแปรตัว อักษร (char) จะกําหนดคาภายในเครืองหมายคํ ่ าพูดขีดเดียว 'A'
32 Arduino IDE
1.8.10 ตัวแปรอะเรย (array) ตัวแปรอะเรยเปนตัวแปรหลายตัว ทีถู่ กเก็บรวมอยูในตั วแปรชือเดี ่ ยวกัน โดยอางถึงตัวแปรแตละ ตัวดวยหมายเลขดัชนีทีเขี ่ ยนอยูในวงเล็ บสีเหลี ่ ยม ่ ตัวแปรอะเรยของ Arduino จะอางอิงตามภาษา C ตัวแปรอะเรยอาจจะดูซับซอน แตถาใชเพียงตัวแปรอะเรยอยางตรงไปตรงมาจะงายตอการทําความเขาใจ ตัวอยางที่ 1-39 ตัวอยางการประกาศตัวแปรอะเรย int myInts[6]; int myPins[] = {2, 4, 8, 3, 6}; int mySensVals[6] = {2, 4, -8, 3, 2}; char message[6] = “hello”; ผูพั ฒนาโปรแกรมสามารถประกาศตัวแปรอะเรยไดโดยยังไมกําหนดคาของตัวแปร myInts การประกาศตัวแปร myPins เปนการประกาศตัวแปรอะเรยโดยไมระบุขนาด เมือประกาศตั ่ วแปรแลว ตองกําหนดคาทันที เพือให ่ คอมไพเลอรนับวา ตัวแปรมีสมาชิกกีตั่ วและกําหนดคาไดถูกตอง จากตัวอยางมีทังสิ ้ ้น 5 ตัว ฒนาโปรแกรมสามารถประกาศและกําหนดขนาดของตัวแปรอะเรยได ในการประกาศตัวแปรอะเรย ผูพั ในพรอมกันดังตัวอยางการประกาศตัวแปร mySensVals ทีประกาศทั ่ งขนาดและกํ ้ าหนดคา ่ นแบบ char มีตัวอักษร 5 ตัวคือ hello ตัวอยางสุดทายเปนการประกาศอะเรยของตัวแปร message ทีเป แตการกําหนดขนาดของตัวแปรจะตองเผือที ่ สํ่ าหรับเก็บตัวอักษรแจงจบขอความดวย จึงทําใหคาดัชนีตองกําหนดเปน 6
1.8.10.1 การใชงานตัวแปรอะเรย พิมพชือตั ่ วแปรพรอมกับระบุคาดัชนีภายในเครืองหมายวงเล็ ่ บสีเหลี ่ ยม ่ คาดัชนีของตัวแปรอะเรย เริมต ่ นดวย 0 ดังนันค ้ าของตัวแปร mySensVals มีคาดังนี้ mySensVals[0] == 2, mySensVals[1] == 4
การกําหนดคาใหกับตัวแปรอะเรย ทําไดดังนี้ mySensVals[0] = 10;
การเรียกคาสมาชิกของตัวแปรอะเรย ทําไดดังนี้ x = mySensVals[4];
1.8.10.2 อะเรยและคําสั่งวนรอบ for โดยทัวไปจะพบการใช ่ งานตัวแปรอะเรยภายในคําสัง่ for โดยใชคาตัวแปรนับรอบของคําสัง่ for เปนคาดัชนีของตัวแปรอะเรย ดังตัวอยางตอไปนี้ ตัวอยางที่ 1-40 int i; for (i = 0; i < 5; i = i + 1) { Serial.println(myPins[i]); // แสดงคาสมาชิกของตัวแปรอะเรยทีหน ่ าตาง Serial monitor }
Arduino IDE 33
1.9 ขอบเขตของตัวแปร ตัวแปรในภาษา C ที่ใชใน Arduino จะมีคุณสมบัติที่เรียกวา “ขอบเขตของตัวแปร” (scope) ซึ่งแตกตางจากภาษา BASIC ซึ่งตัวแปรทุกตัวมีสถานะเทาเทียมกันหมดคือ เปนแบบ global
1.9.1 ตัวแปรโลคอลและโกลบอล ตัวแปรแบบโกลบอล (global variable) เปนตัวแปรที่ทุกฟงกชั่นในโปรแกรมรูจั ก โดยตอง ประกาศตัวแปร นอกฟงกชั่น สําหรับตัวแปรแบบโลคอลหรือตัวแปรทองถินเป ่ นตัวแปรทีประกาศ ่ ตัวแปรอยูภายในเครืองหมายวงเล็ ่ บปกกาของฟงกชั่น และรูจั กเฉพาะภายในฟงกชั่นนั้น เมื่อโปรแกรมเริมมี ่ ขนาดใหญและซับซอนมากขึ้น การใชตัวแปรโลคอลจะมีประโยชนมาก เนืองจากแน ่ ใจไดวามีแคฟงกชันนั ่ นเท ้ านันที ้ สามารถใช ่ งานตัวแปร ชวยปองกันการเกิดการผิดพลาด เมื่อฟงกชั่นทําการแกไขคาตัวแปรทีใช ่ งานโดยฟงกชั่นอืน่ ตัวอยางที่ 1-41 int gPWMval; void setup() {} void loop() { int i; float f; }
// ทุกฟงกชั่นมองเห็นตัวแปรนี้
// ตัวแปร i จะถูกมองเห็นและใชงานภายในฟงกชั่น loop เทานั้น // ตัวแปร f จะถูกมองเห็นและใชงานภายในฟงกชั่น loop เทานั้น
1.9.2 ตัวแปรสแตติก (static) เปนคําสงวน (keyword) ทีใช ่ ตอนประกาศตัวแปรทีมี่ ขอบเขตใชงานแคภายในฟงกชันเท ่ านัน้ โดยตางจากตัวแปรโลคอลตรงที่ตัวแปรแบบโลคอลจะถูกสรางและลบทิ้งทุกครั้งที่เรียกใชฟงกชั่น สําหรับตัวแปรสแตติกเมื่อจบการทํางานของฟงกชั่นคาตัวแปรจะยังคงอยู (ไมถูกลบทิ้ง) เปนการ รักษาคาตัวแปรไวระหวางการเรียกใชงานฟงกชั่น ตัวแปรที่ประกาศเปน static จะถูกสรางและกําหนดคาในครั้งแรกที่เรียกใชฟงกชั่น
34 Arduino IDE
1.10 คาคงที่ (constants) คาคงที่เปน กลุมตัวอักษรหรือขอความที่ไดกําหนดคาไวลวงหนาแลว ตัวคอมไพเลอรของ Arduino จะรูจักกับคาคงที่เหลานี้แลว ไมจําเปนตองประกาศหรือกําหนดคาคงที่
1.10.1 HIGH, LOW : ใชกําหนดคาทางตรรกะ ในการอานหรือเขียนคาใหกับขาพอรตดิจิตอล คาที่เปนไดมี 2 คาคือ HIGH หรือ LOW HIGH เปนการกําหนดคาใหขาดิจิตอลนั้นมีแรงดันเทากับ +5V สวนการอานคา ถาอาน ได +3V หรือมากกวา ไมโครคอนโทรลเลอรจะอานคาไดเปน HIGH คาคงที่ของ HIGH คือ “1” หรือ เทียบเปนตรรกะคือ จริง (true) LOW เปนการกําหนดคาใหขาดิจิตอลนั้นมีแรงดันเทากับ 0V สวนการอานคา ถาอานได +2V หรือนอยกวา ไมโครคอนโทรลเลอรจะอานคาไดเปน LOW คาคงที่ของ LOW คือ “0” หรือเทียบ เปนตรรกะคือ เท็จ (false)
1.10.2 INPUT, OUTPUT : กําหนดทิศทางของขาพอรตดิจิตอล ขาพอรตดิจิตอลทําหนาที่ได 2 อยางคือ เปนอินพุตและเอาตพุต เมื่อกําหนดเปน INPUT หมายถึง กําหนดใหขาพอรตนั้นๆ เปนขาอินพุต เมื่อกําหนดเปน OUTPUT หมายถึง กําหนดใหขาพอรตนั้นๆ เปนขาเอาตพุต
1.11 ตัวกระทําอื่นๆ ที่เกี่ยวของกับตัวแปร 1.11.1 cast : การเปลี่ยนประเภทตัวแปรชัวคราว ่ cast เปนตัวกระทําที่ใชสั่งใหเปลี่ยนประเภทของตัวแปรไปเปนประเภทอื่น และบังคับให คํานวณคาตัวแปรเปนประเภทใหม รูปแบบคําสั่ง (type)variable
เมือ่
Type เปนประเภทของตัวแปรใดๆ (เชน int, float, long) Variable เปนตัวแปรหรือคาคงทีใดๆ ่
ตัวอยางที่ 1-42 int i; float f; f = 4.6; i = (int) f; ในการเปลี่ยนประเภทตัวแปรจาก float เปน int คาที่ไดจะถูกตัดเศษออก ดังนัน้ (int)4.6 จึงกลายเปน 4
Arduino IDE 35
1.11.2 sizeof : แจงขนาดของตัวแปร ใชแจงบอกจํานวนไบตของตัวแปรทีต่ องการทราบคา ซึงเป ่ นทังตั ้ วแปรปกติและตัวแปรอะเรย รูปแบบคําสั่ง เขียนไดสองแบบดังนี้ sizeof(variable) sizeof variable
เมือ่ Variable คือตัวแปรปกติหรือตัวแปรอะเรย (int, float, long) ที่ตองการทราบขนาด
ตัวอยางที่ 1-43 ตัวกระทํา sizeof มีประโยชนอยางมากในการจัดการกับตัวแปรอะเรย (รวมถึงตัวแปรสตริง) ตัวอยางตอไปนีจะพิ ้ มพขอความออกทางพอรตอนุกรมครังละหนึ ้ งตั ่ วอักษร char myStr[] = “this is a test”; int i; void setup() { Serial.begin(9600); } void loop() { for (i = 0; i < sizeof(myStr) - 1; i++) { Serial.print(i, DEC); Serial.print(“ = “); Serial.println(myStr[i], BYTE); } }
36 Arduino IDE
1.12 คําสงวนของ Arduino 1.7.10 ทีใช ่ กับชุดกลองสมองกล IPST-MicroBOX (SE) คําสงวนคือ คาคงที่ ตัวแปร และฟงกชันที ่ ได ่ กําหนดไวเปนสวนหนึงของภาษา ่ C ของ Arduino หามนําคํา เหลานีไปตั ้ งชื ้ อตั ่ วแปร สามารถแสดงไดดังนี้ # Constants
# Datatypes
HIGH LOW INPUT OUTPUT SERIAL DISPLAY PI HALF_PI TWO_PI LSBFIRST MSBFIRST CHANGE FALLING RISING false true null
boolean byte char class default do double int long private protected public return short signed static switch throw try unsigned void
# Literal Constants GLCD_RED GLCD_GREEN GLCD_BLUE GLCD_YELLOW GLCD_BLACK GLCD_WHITE GLCD_SKY GLCD_MAGENTA # Port Constants DDRB PINB PORTB DDRC PINC PORTC DDRD PIND PORTD # Names
popxt
# Methods/Fucntions sw_ok sw_ok_press analog knob glcd glcdChar glcdString glcdMode glcdGetMode glcdFlip glcdGetFlip colorRGB setTextColor setTextBackgroundColor setTextSize getTextColor getTextBackgroundColor getTextSize
glcdFillScreen glcdClear glcdPixel glcdRect glcdFillRect glcdLine glcdCircle glcdFillCircle glcdArc getdist in out motor motor_stop fd bk fd2 bk2 tl tr sl sr servo sound beep uart_set_baud uart_get_baud uart_putc uart_puts uart uart_available uart_getkey uart1_set_baud uart1_get_baud uart1_putc uart1_puts uart1 uart1_available uart1_getkey uart1_flush
# Other abs acos += + [] asin = atan atan2 & &= | |= boolean byte case ceil char char class , // ?: constrain cos {} — default delay delayMicroseconds / /** . else == exp false float float floor for < <= HALF_PI if ++
Arduino IDE 37 != int << < <= log && ! || ^ ^= loop max millis min % /*
* new null () PII return >> ; Serial Setup sin sq sqrt = switch tan this true TWO_PI
void while Serial begin read print write println available digitalWrite digitalRead pinMode analogRead analogWrite attachInterrupts detachInterrupts beginSerial serialWrite serialRead
serialAvailable printString printInteger printByte printHex printOctal printBinary printNewline pulseIn shiftOut compass_read compass_set_heading compass_read_heading compass_writeConfig compass_readConfig
compass_scan encoder popx2
38 Arduino IDE
Arduino IDE 39
Arduino ในการเขียนโปรแกรมภาษา C/C++ ของ Arduino สิ่งหนึงที ่ ่มีบทบาทสําคัญมากคือ ตัวแปร (variable) ในแบบตางๆ เนื่องจากตองใชตัวแปรในการจัดเก็บและประมวลผลขอมูลอยูเสมอ ในบท นีจึ้ งเปนการนําเสนอขอมูลเพิมเติ ่ มทีเกี ่ ยวข ่ องกับการใชงานตัวแปรในลักษระตางๆ เพือประโยชน ่ ใน การพัฒนาโปรแกรมตอไป
2.1 การใชงานตัวแปรอะเรย ตัวแปรอะเรยใชสําหรับจัดเก็บขอมูลชนิดเดียวกันเปนชุดตอๆ กัน ซึงผู ่ ใช งานสามารถกําหนด ขนาดของอะเรยได การประกาศตัวแปรอะเรยทําไดตามตัวอยางตอไปนี้ ตัวอยางที่ 2-1 char s[5];
เปนการประกาศตัวแปร s แบบอะเรยของตัวอักขระหรือเรียกวา สตริง (string) ในภาษา C โดยกําหนด ขนาดเปน 5 เซล
ตัวอยางที่ 2-2 char s[5] ={'a','b','c','d','e'};
// ประกาศตัวแปร s แบบอะเรยพรอมกําหนด
คาเริมต ่ น 5 คา การเขาถึงสมาชิกในแตละเซลของตัวแปรอะเรย ทําไดดังนี้ char ch0 = s[0]; // โหลดคาจากตัวแปรอะเรย s ตําแหนง 0 มาเก็บใน ch0 (คาคือ 'a') char ch1 = s[1]; // โหลดคาจากตัวแปรอะเรย s ตําแหนง 1 มาเก็บใน ch1 (คาคือ 'b') char ch2 = s[2]; // โหลดคาจากตัวแปรอะเรย s ตําแหนง 2 มาเก็บใน ch2 (คาคือ 'c') char ch3 = s[3]; // โหลดคาจากตัวแปรอะเรย s ตําแหนง 3 มาเก็บใน ch3 (คาคือ 'd') char ch4 = s[4]; // โหลดคาจากตัวแปรอะเรย s ตําแหนง 4 มาเก็บใน ch4 (คาคือ 'e')
40 Arduino IDE
ตัวอยางที่ 2-3 char s[6] ={'a','b','c','d','e','\0'}; // ประกาศตัวแปร s
แบบอะเรยพรอมกําหนดคาเริมต ่ น เขาถึงสมาชิกแตละเซลไดดังนี้ char ch0 = s[0]; // โหลดคาจากตัวแปรอะเรย s ตําแหนง 0 มาเก็บใน ch0 (คาคือ 'a') char ch1 = s[1]; // โหลดคาจากตัวแปรอะเรย s ตําแหนง 1 มาเก็บใน ch0 (คาคือ 'b') char ch2 = s[2]; // โหลดคาจากตัวแปรอะเรย s ตําแหนง 2 มาเก็บใน ch0 (คาคือ 'c') char ch3 = s[3]; // โหลดคาจากตัวแปรอะเรย s ตําแหนง 3 มาเก็บใน ch0 (คาคือ 'd') char ch4 = s[4]; // โหลดคาจากตัวแปรอะเรย s ตําแหนง 4 มาเก็บใน ch0 (คาคือ 'e') char ch5 = s[5]; // โหลดคาจากตัวแปรอะเรย s ตําแหนง 5 มาเก็บใน ch0 // (คาคือ '\0' เปนตัวปดทายสตริงซึ่งมีคาเปน 0)
ตัวอยางที่ 2-4 ่ นแบบสายอักขระ char s[6] = "abcde"; // ประกาศตัวแปร s แบบอะเรยพรอมกําหนดคาเริมต เขาถึงสมาชิกแตละเซลไดดังนี้ char ch0 = s[0]; char ch1 = s[1]; char ch2 = s[2]; char ch3 = s[3]; char ch4 = s[4]; char ch5 = s[5];
โหลดคาจากตัวแปรอะเรย s ตําแหนง 0 มาเก็บใน ch0 (คาคือ 'a') // โหลดคาจากตัวแปรอะเรย s ตําแหนง 0 มาเก็บใน ch1 (คาคือ 'b') // โหลดคาจากตัวแปรอะเรย s ตําแหนง 0 มาเก็บใน ch2 (คาคือ 'c') // โหลดคาจากตัวแปรอะเรย s ตําแหนง 0 มาเก็บใน ch3 (คาคือ 'd') // โหลดคาจากตัวแปรอะเรย s ตําแหนง 0 มาเก็บใน ch4 (คาคือ 'e') // โหลดคาจากตัวแปรอะเรย s ตําแหนง 0 มาเก็บใน ch5 // (คาคือ '\0' เปนตัวปดทายสตริงซึ่งมีคาเปน 0) //
ตัวอยางที่ 2-5 char s[] = "abcde";
เปนการประกาศตัวแปร s แบบอะเรยพรอมกําหนดคาเริมต ่ นแบบสายอักขระ โดยไมระบุจํานวนเซล ตัวแปล ภาษาหรือคอมไพเลอรจะกําหนดใหเทากับจํานวนสตริงพรอมกับตัวปดทายใหอัตโนมัติ เขาถึงสมาชิกแตละ เซลไดดังนี้ char ch0 = s[0]; // โหลดคาจากตัวแปรอะเรย s ตําแหนง 0 มาเก็บใน ch0 (คาคือ 'a') char ch1 = s[1]; // โหลดคาจากตัวแปรอะเรย s ตําแหนง 0 มาเก็บใน ch1 (คาคือ 'b') char ch2 = s[2]; // โหลดคาจากตัวแปรอะเรย s ตําแหนง 0 มาเก็บใน ch2 (คาคือ 'c') char ch3 = s[3]; // โหลดคาจากตัวแปรอะเรย s ตําแหนง 0 มาเก็บใน ch3 (คาคือ 'd') char ch4 = s[4]; // โหลดคาจากตัวแปรอะเรย s ตําแหนง 0 มาเก็บใน ch4 (คาคือ 'e') char ch5 = s[5]; // โหลดคาจากตัวแปรอะเรย s ตําแหนง 0 มาเก็บใน ch5 // (คาคือ '\0' เปนตัวปดทายสตริงซึ่งมีคาเปน 0)
Arduino IDE 41
ตัวอยางที่ 2-6 void setup() { Serial.begin(9600);
//
กําหนดอัตราเร็วในการสื่อสารขอมูล 9,600 บิตตอวินาที
} void loop() { char s[6]= "abcde";
//
Serial.println(s);
//
delay(1000);
//
กําหนดสตริง s เก็บอักขระ "abcde" สงผลลัพธไปแสดงที่ Serial Monitor หนวงเวลาในการแสดงผล 1 วินาที
}
2.2 ตัวแปรพอยนเตอรที่ใชรวมกับสตริงภาษา C ตัวแปรพอยนเตอรทําหนาที่เปนตัวชี้แอดเดรสของขอมูลชนิดเดียวกับขอมูลของตัวแปร พอยนเตอรทีทํ่ าการประกาศโดยจะทําหนาทีเข ่ าถึงแอดเดรสของตัวแปรหรือ ขอมูลทีถู่ กชีหรื ้ ออางอิงถึง การประกาศตัวแปรพอยนเตอรหรือตัวชี้สายอักขระทําไดดังนี้ ตัวอยางที่ 2-7 char * p;
// ประกาศตัวแปร p แบบพอยนเตอรของสายตัวอักขระในภาษา C
ตัวอยางที่ 2-8 char * p = "Hello";
้ กขระ "Hello" โดย p จะชีแอดเดรสอั ้ กขระตัวแรก ในทีนี่ คื้ อ ตําแหนงของ ‘H’ // ประกาศตัวแปร p ชีสายอั
ตัวอยางที่ 2-9 ประกาศตัวแปร p ชี้สายอักขระ "Hello" บที่ ch0 (คาคือ 'H') *p; // โหลดคาของขอมูลจากแอดเดรสที่ p ชี้อยูมาเก็ ้ มาเก็ บที่ ch1(คาคือ 'e') *(p+1); // โหลดคาของขอมูลจากแอดเดรสที่ p+1 ชีอยู *(p+2); // โหลดคาของขอมูลจากแอดเดรสที่ p+2 ชีอยู ้ มาเก็ บที่ ch2 (คาคือ 'l') *(p+3); // โหลดคาของขอมูลจากแอดเดรสที่ p+3 ชีอยู ้ มาเก็ บที่ ch3 (คาคือ 'l') ้ มาเก็ บที่ ch4(คาคือ '0') *(p+4); // โหลดคาของขอมูลจากแอดเดรสที่ p+4 ชีอยู บที่ ch5 *(p+5); // โหลดคาของขอมูลจากแอดเดรสที่ p+5 ชี้อยูมาเก็ // (คาคือ '\0' เปนตัวปดทายสตริงซึ่งมีคาเปน 0)
char * p = ”Hello"; char ch0 = char ch1 = char ch2 = char ch3 = char ch4 = char ch5 =
//
42 Arduino IDE
ตัวอยางที่ 2-10 "Hello" ผูพั ฒนาโปรแกรมสามารถใชพอยนเตอรตัวชีสายอั ้ กขระเพือเข ่ าถึงขอมูลในรูปแบบเดียวกับอะเรยไดดังนี้ char * p = "Hello";// ประกาศตัวแปร p ชี้สายอักขระ "Hello" บที่ ch0 (คาคือ 'H') char ch0 = p[0]; // โหลดคาของขอมูลจากแอดเดรสที่ p ชี้อยูมาเก็ char ch1 = p[1]; // โหลดคาของขอมูลจากแอดเดรสที่ p+1 ชีอยู ้ มาเก็ บที่ ch1(คาคือ 'e') char ch2 = p[2]); // โหลดคาของขอมูลจากแอดเดรสที่ p+2 ชีอยู ้ มาเก็ บที่ ch2 (คาคือ 'l') ้ มาเก็ บที่ ch3 (คาคือ 'l') char ch3 = p[3]; // โหลดคาของขอมูลจากแอดเดรสที่ p+3 ชีอยู ้ มาเก็ บที่ ch4(คาคือ '0') char ch4 = p[4]; // โหลดคาของขอมูลจากแอดเดรสที่ p+4 ชีอยู บที่ ch5 char ch5 = p[5]; // โหลดคาของขอมูลจากแอดเดรสที่ p+5 ชี้อยูมาเก็ // (คาคือ '\0' เปนตัวปดทายสตริงซึ่งมีคาเปน 0) char * p = "Hello";
// ประกาศตัวแปร p ชี้สายอักขระ
ตัวอยางที่ 2-11 ตอไปนี้คือตัวอยางการใชพอยนเตอรชี้ไปยังอะเรย เพือเข ่ าถึงขอมูลสายอักขระ char str[] = "ABCDEF"; // ประกาศตัวแปรสตริง str เพือเก็ ่ บคาสายอักขระ "ABCDEF" char * p ; // ประกาศตัวแปร p ชี้สายอักขระ p = str; // กําหนดใหพอยนเตอร p ชี้ไปยังสตริง str char ch0 = *p; // โหลดคาของขอมูลจากแอดเดรสที่ p ชี้อยูมาเก็ บที่ ch0 (คาคือ 'A') char ch1 = *(p+1); // โหลดคาของขอมูลจากแอดเดรสที่ p+1 ชีอยู ้ มาเก็ บที่ ch1(คาคือ 'B') ้ มาเก็ บที่ ch2 (คาคือ 'C') char ch2 = *(p+2); // โหลดคาของขอมูลจากแอดเดรสที่ p+2 ชีอยู ้ มาเก็ บที่ ch3 (คาคือ 'D') char ch3 = *(p+3); // โหลดคาของขอมูลจากแอดเดรสที่ p+3 ชีอยู char ch4 = *(p+4); // โหลดคาของขอมูลจากแอดเดรสที่ p+4 ชีอยู ้ มาเก็ บที่ ch4(คาคือ 'E') char ch5 = *(p+5); // โหลดคาของขอมูลจากแอดเดรสที่ p+5 ชีอยู ้ มาเก็ บที่ ch5 (คาคือ 'F') char ch5 = *(p+6); // โหลดคาของขอมูลจากแอดเดรสที่ p+6 ชี้อยูมาเก็ บที่ ch6 // (คาคือ '\0' เปนตัวปดทายสตริงซึ่งมีคาเปน 0)
Arduino IDE 43
ตัวอยางที่ 2-12 ตัวอยางตอไปนี้แสดงใหเห็นการวนลูปโดยใชพอยนเตอรชี้ไปยังอะเรย เพือเข ่ าถึงขอมูลสายอักขระได Serial.begin(9600); ………………………………… char str[] = "ABCDEF";
// ประกาศตัวแปรสตริง str ใหเก็บคาสายอักขระ "ABCDEF"
ประกาศตัวแปร p ชี้สายอักขระ // กําหนดใหพอยนเตอร p ชี้ไปยังสตริง str // ตรวจสอบวาขอมูลทีพอยน ่ เตอร p ชีอยู ้ มี คาเปน 0 หรือยัง // (ตัวปดทายสตริง '\0')
char * p ;
//
p = str; while(*p)
{ Serial.println(*p++);
พิมพอักขระของสตริง str ทีถู่ กชี้โดย p ออกมาทีละตัวจนครบ ('A' ถึง 'F') ่ าถึงอักขระที่อยูถั ดไป // ทุกครั้งหลังพิมพอักขระออกมา จะเพิ่มคาแอดเดรส 1 คาเพือเข //
}
2.3 การแปลงออบเจ็กตสตริงของ C++ เปนสตริงของภาษา C ทําไดดวยการเรียกผานเมธอด c_str รูปแบบ const char *p c_str()
คืนคาแอดเดรสผลลัพธของการแปลงออบเจ็ตสตริงของ C++ เปนสตริงแบบภาษา C ตัวอยางที่ 2-13 String s = "Hello";
ประกาศตัวแปร p เพือรั ่ บตําแหนงการชีแอดเดรสของออบเจ็ ้ กต String p = s.c_str(); // แปลงออบเจ็กตสตริงใหเปนสตริงแบบภาษา C char ch0 = *p; // โหลดคาของขอมูลจากแอดเดรสที่ p ชี้อยูมาเก็ บที่ ch0 (คาคือ 'H') ้ มาเก็ บที่ ch1(คาคือ 'e') char ch1 = *(p+1); // โหลดคาของขอมูลจากแอดเดรสที่ p+1 ชีอยู char ch2 = *(p+2); // โหลดคาของขอมูลจากแอดเดรสที่ p+2 ชีอยู ้ มาเก็ บที่ ch2 (คาคือ 'l') char ch3 = *(p+3); // โหลดคาของขอมูลจากแอดเดรสที่ p+3 ชีอยู ้ มาเก็ บที่ ch3 (คาคือ 'l') char ch4 = *(p+4); // โหลดคาของขอมูลจากแอดเดรสที่ p+4 ชีอยู ้ มาเก็ บที่ ch4(คาคือ '0') char ch5 = *(p+5); // โหลดคาของขอมูลจากแอดเดรสที่ p+5 ชี้อยูมาเก็ บที่ ch5 // (คาคือ '\0' เปนตัวปดทายสตริงซึ่งมีคาเปน 0) const char * p;
//
44 Arduino IDE
2.4 การแปลงสตริง 2.4.1 การแปลงสตริงของภาษา C เปนเลขจํานวนเต็ม int ทําไดดวยการเรียกผานฟงกชั่น atoi รูปแบบ int atoi(char * p)
พารามิเตอร p คือตัวชีสตริ ้ งทีต่ องการแปลงคาไปเปนตัวเลขจํานวนเต็มแบบ int การคืนคา คืนคาเปนตัวเลขจํานวนเต็มแบบ int ตัวอยางที่ 2-14 char s[] = "1560"; // ประกาศตัวแปรสตริง s เพือกํ ่ าหนดใหเก็บคาของสายอักขระ “1560” int myInt = atoi(s); // แปลงคาสายอักขระ s ใหเปนเลขจํานวนเต็มเก็บไวทีตั ่ วแปร myInt
ผลลัพธคือ myInt เก็บคาตัวเลข 1,560
2.4.2 การแปลงสตริงของภาษา C เปนเลขจํานวนเต็ม long ทําไดดวยการเรียกผานฟงกชั่น atol รูปแบบ long atol(char * p)
พารามิเตอร p คือตัวชีสตริ ้ งทีต่ องการแปลงคาไปเปนตัวเลขจํานวนเต็มแบบ long การคืนคา คืนคาเปนตัวเลขจํานวนเต็มแบบ long ตัวอยางที่ 2-15 char s[] = "12345678"; //
ประกาศตัวแปรสตริง s กําหนดใหเก็บคาของสายอักขระ "12345678"
long myLong = atol(s); // แปลงคาของสายอักระ s ใหเปนเลขจํานวนเต็ม long เก็บไวทีตั ่ วแปร myLong
ผลลัพธคือ myLong เก็บคาตัวเลข 12,345,678
Arduino IDE 45
2.4.3 การแปลงสตริงของภาษา C เปนเลขทศนิยม float ทําไดดวยการเรียกผานฟงกชั่น atof รูปแบบ float atof(char * p)
พารามิเตอร p คือตัวชีสตริ ้ งทีต่ องการแปลงคาไปเปนตัวเลขทศนิยมแบบ float การคืนคา คืนคาเปนตัวเลขเลขทศนิยมแบบ float ตัวอยางที่ 2-16 ประกาศตัวแปรสตริง s เก็บคาสายอักขระ "162.864" float myFloat = atof(s); // แปลงสายอักระ s เปนเลขทศนิยม float เก็บไวทีตั่ วแปร myFloat ผลลัพธคือ myFloat เก็บคาตัวเลข 162.864 char s[] = "162.864";
//
2.4.4 การแปลงสตริงของภาษา C เปนสายอักขระ ทําไดดวยการเรียกผานฟงกชั่น sprintf รูปแบบ sprintf ( char * str, const char * format, ... );
พารามิเตอร str คือบัฟเฟอรสตริงทีนํ่ ามารับคาผลลัพธทีได ่ จากการแปลง format คือรูปแบบสตริงทีกํ่ าหนดได … คือลําดับของอะกิวเมนตทีสอดรั ่ บกับ format ตัวอยางที่ 2-17 แปลงเลขจํานวนเต็มเปนสตริง char s[20];
// ประกาศตัวแปรสตริง s สําหรับเก็บคาจากผลลัพธการแปลงสตริง
sprintf(s,"Value: %d Volte",30); // แปลงคาเลขจํานวนเต็มรวมกับสตริงและอักขระบังคับ %d
ผลลัพธคือ s เก็บคาสตริงเปน "Value: 30 Volte"
ตัวอยางที่ 2-18 แปลงอักขระรวมกับสตริง char s[20];
// ประกาศตัวแปรสตริง s สําหรับเก็บคาจากผลลัพธการแปลงสตริง
sprintf(s,"f(%c) = 3x+1",'x'); //
ผลลัพธคือ s เก็บคาสตริงเปน "f(x) = 3x+1"
แปลงอักขระรวมกับสตริงและอักขระบังคับ %c
46 Arduino IDE
2.4.5 การแปลงขอมูลตัวเลขเปนสตริงของภาษา C ทําไดดวยการเรียกผานฟงกชั่น dtostrf รูปแบบ dtostrf (float f_val, byte min, byte digit , char *str);
พารามิเตอร f_val คือเลขทศนิยมทีต่ องการแปลง min คือจํานวนหลักขอมูลขันตํ ้ าที ่ ได ่ จากการแปลง digit คือความละเอียดของหลักทศนิยม str คือบัฟเฟอรสตริงทีนํ่ ามารับคาผลลัพธทีได ่ จากการแปลง ตัวอยางที่ 2-19 char s[20];
// ประกาศตัวแปรสตริง s สําหรับเก็บคาจากผลลัพธการแปลงสตริง
float f = 123456.589468; // ประกาศตัวแปรเลขทศนิยม กําหนดคาเปน 123,456.589468 dtostrf(f,4,3,s);
// แปลงเลขทศนิยมเปนสตริงจากคาของตัวแปร f
จํานวนหลักทังหมดที ้ ได ่ จะมีอยางนอย 4 หลัก // การแปลงคากําหนดใหมีเลขทศนิยม 3 ตําแหนง ่ จากการแปลงเก็บไวทีสตริ ่ งs // ผลลัพธทีได ผลลัพธคือ s เก็บคาสตริงเปน "123456.589" //
Arduino IDE 47
2.5 การใชงานคลาสสตริง (string) ใน C++ ของ Arduino เบื้องตน 2.5.1 การประะกาศตัวแปรดวยคลาสสตริง การกําหนดชนิดขอมูลสําหรับใชจัดการสายอักขระหรือกลุมขอความใน C++ ของ Arduino สามารถใชคลาส String (สตริง) เปนตัวจัดการสวนนีได ้ การประกาศตัวแปรออบเจ็กตสตริง (String) อยางเปนทางการทําไดดังนี้ // กําหนดใหตัวแปร str เปนออบเจ็กตสตริง
String str;
str = String("My String"); // กําหนดใหตัวแปร str เก็บขอความ "My String"
จากบรรทัดขางตนอาจประกาศเปน str = "My String";
หรือ String str = "My String";
นอกจากนี้ ยังทําการสรางและกําหนดคาเริ่มตนใหกับออบเจ็กตสตริงไดหลายแบบ ดังนี้ String str = //
String('a');
กําหนดอักขระ 'a' ใหเปนคาเริมต ่ นของออบเจ็กต str
String str =
String(13);
่ นสตริง "13" นําไปเปนคาเริมต ่ นของออบเจ็กต str // กําหนดใหตัวเลข 13 เมือแปลงไปเป String str = //
String(120, DEC);
กําหนดใหตัวเลข 120 (ฐานสิบ) แปลงเปนสตริง "120" นําไปเปนคาเริมต ่ นของออบเจ็กต str
String str =
String(62, HEX);
่ นของออบเจ็กต str // กําหนดใหตัวเลข 120 (ฐานสิบหก) แปลงเปนสตริง "3e" นําไปเปนคาเริมต String str =
String(255, BIN);
่ นของออบเจ็กต str // กําหนดใหตัวเลข 255 (ฐานสอง) แปลงเปนสตริง "11111111" นําไปเปนคาเริมต String str =
String(7.584, 2);
กําหนดใหตัวเลข 7.584 เมื่อแปลงเปนสตริง ตองแสดงเลขทศนิยม 2 ตําแหนง "7.58" // และใชเปนคาเริมต ่ นของออบเจ็กต str //
48 Arduino IDE
2.5.2 การเชือมต ่ อสตริงดวยโอเปอเรเตอร += ผูพัฒนาโปรแกรมสามารถเชื่อมตอสตริง 2 ชุดเขาดวยกันดวยโอเปอเรเตอร += หรืออาจเรียก ผานเมธอด concat รูปแบบ boolean concat(param)
ทําหนาทีเชื ่ อมต ่ อสตริง 2 ชุดเขาดวยกัน พารามิเตอร param คือ สตริงทีนํ่ ามาเชือมต ่ อดวย การคืนคา - เปน true เมือข ่ อความของสตริงทีเปรี ่ ยบเทียบตรงกัน - เปน false เมือข ่ อความของสตริงทีเปรี ่ ยบเทียบไมตรงกัน ตัวอยางที่ 2-20 กําหนดใหตัวแปร s เก็บขอความ "Hello " ่ บอยูในตั วแปร s s += "World"; // นําขอความ "World" มาตอทายสตริงทีเก็ ผลลัพธคือ s เก็บขอความสุดทายเปน "Hello World" String
s = String("Hello ");//
ตัวอยางที่ 2-21 String
s = String("Hello ");
// กําหนดใหตัวแปร s เปนออบเจ็กตสตริงเก็บขอความ "Hello " s.concat("World");
่ บอยูในตัวแปร s // นําขอความ "World" มาตอทายสตริงทีเก็ ผลลัพธคือ s เก็บขอความสุดทายเปน "Hello World"
ตัวอยางที่ 2-22 String // int
s = String("Value: ");
กําหนดใหตัวแปร s เปนออบเจ็กตสตริงเก็บขอความ "Value: " value = 500;
// กําหนดใหตัวแปร value เปนชนิดเลขจํานวนเต็มและกําหนดคาเปน 500 s += value;
นําคา 500 ของตัวแปร value แปลงเปนขอความ "500" มาตอทายสตริงทีเก็ ่ บอยูในตัวแปร s ผลลัพธคือ s เก็บขอความสุดทายเปน "Value: 500" //
Arduino IDE 49
ตัวอยางที่ 2-23 #define ANALOG_PIN 0
//
กําหนดใชงานพอรตอะนาลอก A0
void setup() { Serial.begin(9600); while (!Serial);
กําหนดอัตราเร็วของการสื่อสารขอมูล 9,600 บิตตอวินาที // รอจนกระทั่งโมดูลสื่อสารอนุกรม 0 พรอมทํางาน //
} void loop() { float k = (float)(analogRead(0) * 5.0)/1024.0; //
อานคาสัญญาณอะนาลอกเพือแปลงเป ่ นแรงดันไฟฟาชวง 0 ถึง +5 V
String s1= "Value: "; //
ประกาศใชงานตัวแปรสตริง s1 กําหนดคาสตริงเปน "Value: "
String value = String(k,2);
ประกาศใชงานตัวแปรสตริง value กําหนดคาสตริงเปนคาที่ไดจากแปลงของตัวแปร value // ซึ่งเปนเลขทศนิยม โดยกําหนดใหเปนเลขทศนิยม 2 ตําแหนง s1 +=value; // นําสตริงมาเชือมต ่ อกันเพือเตรี ่ ยมแสดงผลตอไป ่ าตาง Serial Monitor Serial.println(s1); // สงผลลัพธไปแสดงทีหน delay(1000); // หนวงเวลาในการแสดงผล 1 วินาที //
}
50 Arduino IDE
2.6 การเปรียบเทียบสตริงดวยโอเปอเรเตอร == และ != ผูพัฒนาโปรแกรมสามารถเปรียบเทียบสตริง 2 ชุดวา เก็บคาตรงกันหรือไมดวยโอเปอเรเตอร == หรืออาจเรียกผานเมธอด equals และเมื่อตองการเปรียบเทียบวา สตริง 2 ชุดเก็บคาสตริงไมตรง กันหรือไม จะใชโอเปอเรเตอร != รูปแบบ boolean equals(param)
ทําหนาที่เปรียบเทียบสตริง 2 ชุด พารามิเตอร param คือ สตริงทีนํ่ ามาเปรียบเทียบ การคืนคา - เปน true เมือข ่ อความของสตริงทีเปรี ่ ยบเทียบตรงกัน - เปน false เมือข ่ อความของสตริงทีเปรี ่ ยบเทียบไมตรงกัน ตัวอยางที่ 2-24 Serial.begin(9600); String s1 = "Hello"; String s2 = "Hello"; if(s1==s2)
กําหนดคาอัตราเร็วของการสื่อสารขอมูล 9600 บิตตอวินาที // กําหนดใหตัวแปร s1 เปนออบเจ็กตสตริงเก็บขอความ "Hello" // กําหนดใหตัวแปร s2 เปนออบเจ็กตสตริงเก็บขอความ "Hello" // เปรียบเทียบ สตริง s1 และ s2 วา มีขอความตรงกันหรือไม //
{ Serial.println("s1 and s2 is equals."); // พิมพขอความออกไปยังหนาตาง Serial
Monitor ในกรณีทีสตริ ่ ง s1 และ s2 มีขอความตรงกัน
} else { Serial.println("s1 and s2 is not equals.");
่ ง s1 และ s2 มีขอความไมตรงกัน // พิมพขอความออกไปยังหนาตาง Serial Monitor ในกรณีทีสตริ }
ผลลัพธคือ เงือนไขการเปรี ่ ยบเทียบสตริง s1 และ s2 จะเปนจริงเนืองจากทั ่ ้งคูมี ขอความตรงกันทําใหมี การพิมพขอความแสดงผลลัพธออกที่ Serial Monitor เปน "s1 and s2 is equals."
Arduino IDE 51
ตัวอยางที่ 2-25 Serial.begin(9600);
// กําหนดคาอัตราเร็วในการสือสารข ่ อมูลอนุกรม 9600 บิตตอวินาที
String s1 = "Hello"; // กําหนดใหตัวแปร s1 เปนออบเจ็กตสตจริงเก็บขอความ "Hello" String s2 = "Hello"; // กําหนดใหตัวแปร s2 เปนออบเจ็กตสตริงเก็บขอความ "Hello" if(s1!=s2) //
เปรียบเทียบ สตริง s1 และ s2 วา มีขอความไมตรงกันหรือไม
{ Serial.println("YES!"); // พิมพขอความ YES! ไปยังหนาตาง Serial Monitor ในกรณีทีสตริ ่ ง s1 และ s2 มีขอความไมตรงกัน } else { Serial.println("NO!");
่ ง s1 และ s2 มีขอความตรงกัน // พิมพขอความ NO! ออกไปยังหนาตาง Serial Monitor ในกรณีทีสตริ }
ผลลัพธคือ เงือนไขการเปรี ่ ยบเทียบสตริง s1 และ s2 จะเปนเท็จเนื่องจากทั้งคูมี ขอความตรงกัน ทําให มีการพิมพขอความแสดงผลลัพธออกที่ Serial Monitor เปน "NO!"
2.7 ตรวจสอบจํานวนอักขระที่เก็บภายในตัวแปรสตริงดวยเมธอด length เมือต ่ องการตรวจสอบจํานวนอักขระทีเก็่ บภายในสตริงวามีกีตั่ ว ทําไดโดยเรียกผานเมธอด length รูปแบบ int length()
เมธอดตรวจสอบจํานวนอักขระทีเก็ ่ บภายในตัวแปรสตริง ตัวอยางที่ 2-26 String s1= "Hello";
// กําหนดใหตัวแปร s1 เปนออบเจ็กตสตริงเก็บขอความ “Hello”
int result = s1.length(); // อานคาจํานวนสตริงทีถู่ กเก็บไวในตัวแปรสตริง s1 เก็บไวทีตั่ วแปร result
ผลลัพธคือ ตัวแปร result จะมีผลลัพธเทากับ 5
ตัวอยางที่ 2-27 String s1= "Hello World!";
้ 12 ตัว) // กําหนดใหตัวแปร s1 เปนออบเจ็กตสตริงเก็บขอความ "Hello World!"(อักขระทังหมด int result = s1.length();
่ กเก็บไวในตัวแปรสตริง s1 มาเก็บไวทีตั่ วแปร result // อานคาจํานวนของสตริงทีถู ผลลัพธคือ ตัวแปร result จะมีผลลัพธเทากับ 12 (รวมอักขระชองวางดวย)
52 Arduino IDE
2.8 การแปลงสตริงดวยเมธอดตางๆ 2.8.1 แปลงสตริงใหเปนขอมูลเลขจํานวนเต็มดวยเมธอด toInt เมือต ่ องการแปลงอักขระทีเก็ ่ บภายในออบเจ็กตสตริงเปนเลขจํานวนเต็มชนิด long ทําไดโดย ใชเมธอด toInt รูปแบบ long toInt()
คืนคาเปนเลขจํานวนเต็มที่ไดจากการแปลงอักขระทีเก็ ่ บภายในสตริง ตัวอยางที่ 2-28 String s1= "200";
// กําหนดใหตัวแปร s1 เปนออบเจ็กตสตริงเก็บขอความ "200"
long result = s1.toInt();// แปลงสตริง s1 เปนตัวเลขจํานวนเต็ม เก็บไวทีตั ่ วแปร result
ผลลัพธคือ ตัวแปร result จะมีผลลัพธเทากับ 200
2.8.2 แปลงสตริงใหเปนขอมูลเลขทศนิยมดวยเมธอด toFloat กระทําไดโดยใชเมธอด toFloat รูปแบบ long toFloat()
คืนคาเปนเลขทศนิยมที่ไดจากการแปลงอักขระที่เก็บภายในสตริง ตัวอยางที่ 2-29 String s1= "46.587"; // กําหนดใหตัวแปร s1 เปนออบเจ็กตสตริงเก็บขอความ "46.587" float result = s1.toFloat();
่ วแปร result // แปลงสตริง s1 ออกมาเปนตัวเลขทศนิยมเก็บไวทีตั ผลลัพธคือ ตัวแปร result จะมีผลลัพธเทากับ 46.59
Arduino IDE 53
2.9 คัดลอกซับสตริงดวยเมธอด substring เมือต ่ องการคัดลอกอักขระยอยทีเก็ ่ บภายในออบเจ็กตสตริง เพือนํ ่ าไปใชประมวลผลบางอยาง ทําไดโดยใชเมธอด substring ซึ่งมีใหเลือกใชงาน 2 รูปแบบ
14.1 String
substring(from)
พารามิเตอร from คือ ตําแหนงดัชนีชีลํ้ าดับของอักขระภายในสตริงวา ตองการใหเริ่มตนการคัดลอก ตังแต ้ ดัชนีตัวที่กําหนดไปจนถึงลําดับสุดทาย (ดัชนีตัวชีลํ้ าดับของอักขระตัวแรกเริมที ่ ่ 0) การคืนคา คืนคาเปนสตริง ผลลัพธออกมาในรูปแบบของออบเจ็กตสตริงตามทีต่ องการ
14.2 String substring(from,to) พารามิเตอร from คือ ตําแหนงดัชนีตัวชีลํ้ าดับของอักขระภายในสตริงวา ตองการใหเริมต ่ นการคัดลอก ตังแต ้ ดัชนีตัวที่กําหนดไปจนถึงลําดับสุดทาย (ดัชนีตัวชีลํ้ าดับของอักขระตัวแรกจะเริ่มที่ 0) to คือ ตําแหนงดัชนีตัวชีลํ้ าดับของอักขระตัวสุดทายบวกหนึ่งลําดับ การคืนคา คืนคาเปนสตริง ผลลัพธออกมาในรูปแบบของออบเจ็กสตริง ตัวอยางที่ 2-30 String s1= "abcdefghijklmnopqrstuvwxyz";
กําหนดใหตัวแปร s1 เปนออบเจ็กตสตริงเก็บขอความ a ถึง z String result = s1.substring(2);// คัดลอกอักขระตําแหนงดัชนีที่ 2 จนถึงตัวสุดทาย ผลลัพธคือ ตัวแปร result จะมีผลลัพธเปน "cdefghijklmnopqrstuvwxyz" //
ตัวอยางที่ 2-31 String s1= "abcdefghijklmnopqrstuvwxyz"; //
กําหนดใหตัวแปร s1 เปนออบเจ็กตสตริงเก็บขอความ a ถึง z
String result = s1.substring(2,5);
คัดลอกอักขระที่ตําแหนงดัชนีที่ 2 จนถึง 4 (กอนถึงดัชนีลําดับที่ 5) ผลลัพธคือ ตัวแปร result จะมีผลลัพธเปน "cde" //
54 Arduino IDE
2.10 คนหาตําแหนงของอักขระภายในสตริงดวยเมธอด indexOf เมื่อตองการคัดลอกอักขระยอยที่เก็บอยูภายในออบเจ็กตสตริง เพื่อนําไปใชประมวลผล บางอยางได ทําไดโดยใชเมธอด indexOf ซึ่งมีใหเลือกใชงาน 2 รูปแบบ รูปแบบที่ 1 int indexOf(ch)
พารามิเตอร ch คือ อักขระเปาหมายทีต่ องการคนหาตําแหนงภายในสตริง การคืนคา คืนคาเปนตําแหนงตัวชีอั้ กขระ ch ภายในสตริงตัวแรกสุดทีพบ ่ กรณีไมพบ คืนคาเปน -1 รูปแบบที่ 2 int indexOf(ch,start)
พารามิเตอร ch คือ อักขระเปาหมายทีต่ องการคนหาตําแหนงภายในสตริง start คือ ตําแหนงดัชนีตัวชีลํ้ าดับเริมต ่ นสําหรับการคนหาอักขระ การคืนคา คืนคาเปนตําแหนงตัวชีอั้ กขระ ch ภายในสตริงตัวแรกสุดทีพบ ่ กรณีไมพบ คืนคาเปน -1 ตัวอยางที่ 2-32 String s1= "Hello World";
// ตัวแปร s1 เก็บขอความ "Hello World"
int result = s1.indexOf('W'); // คนหาตําแหนงอักขระ 'W' ผลลัพธเก็บทีตั่ วแปร result
ผลลัพธคือ ตัวแปร result จะมีคาเปน 6(ตําแหนงของอักขระ ‘W’)
ตัวอยางที่ 2-33 String s1= "Hello World";
// ตัวแปร s1 เก็บขอความ "Hello World"
int first = s1.indexOf('o'); // คนหาตําแหนงอักขระ 'o' ตัวแรก เก็บผลลัพธไวทีตั ่ วแปร first int second = s1.indexOf('o',first+1); // คนหาตําแหนงอักขระ 'o' ตัวทีสองถั ่ ดไป เก็บผลลัพธไวทีตั่ วแปร second
ผลลัพธคือ ตัวแปร first จะมีคาเปน 4 (ตําแหนงของอักขระ 'o' ตัวแรก) ตัวแปร second จะมีคาเปน 7(ตําแหนงของอักขระ 'o' ตัวทีสอง) ่
Arduino IDE 55
Arduino ทางผูจั ดทําซอฟตแวร Arduino IDE ไดจัดเตรียมฟงกชันพื ่ นฐาน ้ เชน ฟงกชันเกี ่ ยวกั ่ บขาพอรต อินพุตเอาตพุตดิจิตอล, อินพุตเอาตพุตอะนาลอก เปนตน ดังนันในการเขี ้ ยนโปรแกรมจึงเรียกใชฟงกชัน่ เหลานีได ้ ทันที นอกจากฟงกชันพื ่ นฐานเหล ้ านีแล ้ ว นักพัฒนาทานอืนๆ ่ ทีร่ วมในโครงการ Arduino นีก็้ ไดเพิมไลบรารี ่ อืนๆ ่ เชน ไลบรารีควบคุมมอเตอร, การติดตอกับอุปกรณบัส I2C ฯลฯ ในการเรียกใชงาน ตองเพิมบรรทั ่ ด #include เพือผนวกไฟล ่ ทีเหมาะสมก ่ อน จึงจะเรียกใชฟงกชันได ่ ในบทนี้จะอธิบายถึงการเรียกใชฟงกชั่นและตัวอยางโปรแกรมสําหรับทําการทดลอง โดยใช แผงวงจร IPST-SE เปนอุปกรณหลักในการทดลอง โดยมีขั้นตอนในการทดสอบดังนี้ (3.1) เปดโปรแกรม Arduino IDE 1.7.10 แลวเชื่อมตอแผงวงจร IPST-SE เขากับ คอมพิวเตอรผานพอรต USB (3.2) เลือกฮารดแวรหรือบอรดเปน IPST-SE (3.3) เลือกพอรตเชื่อมตอใหถูกตอง (3.4) พิมพโปรแกรมลงในหนาตางเอดิเตอรของ Arduino IDE (3.5) บันทึกไฟล นามสกุล .ino แลวทําการคอมไพล โดยคลิกที่ปุม หรือเลือกเมนู Sketch > Verfy/Compile (3.6) หากการคอมไพลถูกตอง ทําการทดสอบการทํางานบนแผงวงจร IPST-SE ดวยการ อัปโหลดโปรแกรม โดยคลิกที่ปุม หรือเลือกที่เมนู File > Upload (3.7) เมือการอั ่ ปโหลดเสร็จสิน้ แผงวงจร IPST-SE จะทํางานตามโปรแกรมทีกํ่ าหนดทันที
56 Arduino IDE
3.1 ฟงกชันใช ่ งานพอรตเอาตพุตดิจิตอลของแผงวงจร IPST-SE 3.1.1 คุณสมบัติของขาพอรตเอาตพุต สําหรับขาพอรตที่กําหนดใหเปนเอาตพุตจะมีสถานะเปนอิมพีแดนซตํ่า ทําใหสามารถ จายกระแสไฟฟาใหกับวงจรภายนอกไดสูงถึง 20mA ซึงเพี ่ ยงพอสําหรับขับกระแสให LED สวาง (ตอง ตอตัวตานทานอนุกรมดวย) หรือใชกับตัวตรวจจับตางๆ ได แตไมเพียงพอสําหรับขับรีเลย โซลีนอยด หรือมอเตอร กอนที่จะใชงานขาดิจิตอลของแผงวงจร IPST-SE จะตองสั่งกอนวาใหขาพอรตนี้ทํา หนาทีเป ่ นอินพุตหรือเอาตพุต
3.1.2 การกําหนดโหมดของขาพอรต กอนใชงานตองกําหนดโหมดการทํางานของขาพอรตดิจิตอลใหเปนอินพุตหรือเอาตพุต กําหนดไดจากฟงกชั่น pinMode()มีรูปแบบดังนี้ pinmode(pin,mode);
เมือ่
pin คือ หมายเลขขาที่ตองการ Mode คือ โหมดการทํางาน (INPUT หรือ OUTPUT)
หลังจากที่กําหนดใหเปนเอาตพุตแลวเมื่อตองการเขียนคาไปยังขานั้นๆ ใหเรียกใชฟงกชั่น digitalWrite() โดยมีรูปแบบดังนี้ digitalWrite(pin,value);
เมือ่
pin คือหมายเลขขาที่ตองการ value สถานะลอจิกทีต่ องการ (HIGH หรือ LOW)
analogWrite(pin, value)
pinMode(pin,INPUT)
pinMode(pin,OUTPUT)
digitalWrite(pin, value)
HIGH LOW
รูปที่ 3-1 ไดอะแกรมแสดงกลไกการกําหนดใหขาพอรตของ Arduino และแผงวงจร IPST-SE เปน พอรตเอาตพุตดิจิตอล (บล็อกสีเทาแทนการทํางานหรือเงือนไขที ่ ต่ องการ)
Arduino IDE 57
3.1.3 คําอธิบายและการเรียกใชฟงกชัน่ 3.1.3.1 pinMode(pin,mode) ใชกําหนดขาพอรตใดๆ ใหเปนพอรตดิจิตอล พารามิเตอร pin - หมายเลขขาพอรตของแผงวงจร IPST-SE (คาเปน int) mode - โหมดการทํางานเปน INPUT (อินพุต) หรือ OUTPUT (เอาตพุต) (คาเปน int) ตองใชตัวพิมพใหญ
ตัวอยางที่ 3-1 int ledPin = 17; void setup() { pinMode(ledPin, OUTPUT); } void loop() { digitalWrite(ledPin, HIGH); delay(1000); digitalWrite(ledPin, LOW); delay(1000); }
// ตอ ZX-LED ทีพอร ่ ตหมายเลข 17 // กําหนดเปนเอาตพุต // LED ติดสวาง // หนวงเวลา 1 วินาที // LED ดับ // หนวงเวลา 1 วินาที
3.1.3.2 digitalWrite(pin,value) สั่งงานใหขาพอรตมีคาสถานะเปนลอจิกสูง (HIGH หรือ “1”) หรือลอจิกตํ่า (LOW หรือ “0”) พารามิเตอร pin - หมายเลขขาพอรตของแผงวงจร IPST-SE (คาเปน int) value - มีคา HIGH หรือ LOW
ตัวอยางที่ 3-2 int ledPin = 17; // ตอ ZX-LED ทีพอร ่ ตหมายเลข 17 void setup() { pinMode(ledPin, OUTPUT); // กําหนดเปนเอาตพุต } void loop() { digitalWrite(ledPin, HIGH); // LED ติดสวาง delay(500); // หนวงเวลา 0.5 วินาที digitalWrite(ledPin, LOW); // LED ดับ delay(500); // หนวงเวลา 0.5 วินาที } กําหนดใหพอรตหมายเลข 17 เปน HIGH (มีลอจิกเปน “1”) หนวงเวลา 0.5 วินาที แลวจึงสั่งใหกลับเปน LOW (มีลอจิกเปน “0”) อีกครั้ง วนเชนนี้ไปตลอด
58 Arduino IDE
3.2 ฟงกชันใช ่ งานพอรตอินพุตดิจิตอลของแผงวงจร IPST-SE 3.2.1 คุณสมบัติของขาพอรตอินพุต ขาพอรตของ Arduino และแผงวงจร IPST-SE จะถูกกําหนดเปนอินพุตตั้งแตเริ่มตน จึงไมจํา เปนตองใชฟงกชั่น pinMode() ในการกําหนดใหเปนอินพุต ขาพอรตที่ถูกกําหนดเปนอินพุตจะมี สถานะเปนอิมพีแดนซสูง ทําใหมีความตองการกระแสไฟฟาจากอุปกรณทีต่ องการอานคาอินพุตนอย มาก ทําใหไมสามารถรับหรือจายกระแสใหกับวงจรภายนอก ทําใหนําขาทีเป ่ นอินพุตนีไปใช ้ งานบาง ประเภท เชน สรางตัวตรวจจับการสัมผัสที่อาศัยการวัดคาความจุไฟฟา สําหรับขาอินพุต เมือไม ่ มีอินพุตปอนใหจะตองกําหนดคาแรงดันใหแนนอน ทําไดโดยตอตัวตาน ทานพูลอัป (pull-up resistor) โดยตอขาของตัวตานทานขาหนึงไปยั ่ งไฟเลียง ้ หรือตอพูลดาวน (pull- down) ซึงต ่ อขาหนึงของตั ่ วตานทานจากขาพอรตลงกราวด คาตัวตานทานทีใช ่ ทัวไปคื ่ อ 10k ดังรูปที่ 3-2 แผงวงจร POP- X2 มีจุดตอพอรตดิจิตอลทีกํ่ าหนดใหเปนอินพุตหรือเอาตพุตจํานวน 16 จุดตอ หรือ 16 ขา ถาตองการกําหนดเปนอินพุตตองกําหนดดวยฟงกชัน่ pinMode และอานคาอินพุตไดจาก ฟงกชั่น digitalRead ซึ่งมีรูปแบบดังนี้ digitalRead(pin);
เมือ่ pin คือหมายเลขขาที่ตองการอานคาสถานะ เมือฟ ่ งกชั่นทํางาน จะคืนคาเปนสถานะของขาที่ตองการอานคา โดยคืนคาเปน LOW (คาเปน “0”) หรือ HIGH (คาเปน “1”) +Vcc
ปกติเปนลอจิกต่ํา (LOW หรือ "0") Rpull-up Di
INPUT
ปกติเปนลอจิกสูง (HIGH หรือ "1")
(ก) การตอตัวตานทานพูลอัป
Di
INPUT Rpull-down
(ข) การตอตัวตานทานพูลดาวน
รูปที่ 3-2 แสดงการตอตัวตานทานเพื่อกําหนดสภาวะของขาพอรตอินพุตของไมโครคอนโทรลเลอร ในขณะทียั่ งไมมีอินพุตสงเขามา
Arduino IDE 59
+Vcc
20k
สั่งใหตอตัวตานทาน พูลอัปภายในดวยคําสั่ง digitalWrite(pin, HIGH) Di
Digital input port
รูปที่ 3-3 แสดงการตอตัวตานทานพูลอัปภายในที่พอรตอินพุตดิจิตอลของไมโครคอนโทรลเลอรซึ่ง ควบคุมไดดวยกระบวนการทางซอฟตแวร ภายในขาพอรตของไมโครคอนโทรลเลอร ATmega644P ซึงเป ่ นไมโครคอนโทรลเลอรหลัก ของแผงวงจร IPST-SE จะมีการตอตัวตานทานพูลอัปคา 20k เตรียมไวให สั่งการเพื่อตอใชงานผาน ทางซอฟตแวร ดังรูปที่ 3-3 ในรูปที่ 3-4 แสดงไดอะแกรมการเขียนคําสังเพื ่ อกํ ่ าหนดใหใชงานขาพอรตของไมโครคอนโทรล เลอรหลักของแผงวงจร IPST-SE ทํางานเปนขาพอรตอินพุตดิจิตอล
digitalWrite(pin, HIGH)
pinMode(pin,INPUT)
pinMode(pin,OUTPUT)
val = digitalRead(pin);
val
รูปที่ 3-4 ไดอะแกรมแสดงกลไกการกําหนดใหขาพอรตของ Arduino และแผงวงจร IPST-SE เปนพอรต อินพุตดิจิตอล (บล็อกสีเทาแทนการทํางานหรือเงือนไขที ่ ต่ องการ)
60 Arduino IDE
3.2.2 ตัวอยางการเรียกใชฟงกชันเพื ่ อใช ่ งานพอรตอินพุตดิจิตอล 3.2.2.1 int
digitalRead(pin)
อานคาสถานะของขาที่ระบุไววามีคาเปน HIGH หรือ LOW พารามิเตอร pin - ขาพอรตทีต่ องการอานคา ซึ่งตองเปนขาพอรตดิจิตอล มีคาไดจาก 0 ถึง 30 หรือเปนตัวแปรทีมี่ คา อยูในช วง 0 ถึง 30 ก็ได
คาที่สงกลับ เปน HIGH หรือ LOW
ตัวอยางที่ 3-3 int ledPin = 17; // ตอ ZX-LED ทีพอร ่ ตหมายเลข 17 int inPin = 18; // ตอ ZX-SWITCH01 ทีพอร ่ ตหมายเลข 18 int val = 0; // กําหนดเตัวแปรสําหรับเก็บคาที่อานไดจากอินพุต void setup() { pinMode(ledPin, OUTPUT); // กําหนดใหพอรต 29 เปนเอาตพุต pinMode(inPin, INPUT); // กําหนดใหพอรต 18 เปนอินพุต } void loop() { val = digitalRead(inPin); // อานคาจากพอรตอินพุต digitalWrite(ledPin, val); // แสดงคาที่อานไดทีพอร ่ ตเอาตพุต ในทีนี่ ่คือ พอรต 17 } เมือไม ่ กดสวิตช สถานะทีพอร ่ ต 18 เปน “1” ทําใหพอรต 17 มีสถานะเปน”1” เชนกัน LED ทีต่ อกับพอรต 17 จึงติดสวาง เมื่อกดสวิตช สถานะลอจิกทีพอร ่ ต 18 จะเปน “0” พอรต 17 จึงมีสถานะเปน “0” เชน กัน LED ทีต่ ออยูจึ งดับ หมายเหตุ : ขาพอรตในโปรแกรมนี้อางถึงจุดตอพอรตของแผงวงจร IPST-SE
Arduino IDE 61
3.3 ฟงกชันเกี ่ ่ยวกับการสือสารผ ่ านพอรตอนุกรม ใชสื่อสารขอมูลระหวางฮารดแวร Arduino (ในที่นี้คือแผงวงจร IPST-SE) กับคอมพิวเตอร โดยกระทําผานพอรต USB ในรูปที่ 3-5 แสดงกลไกการทํางานของฟงกชั่น Serial ใน Arduino IDE นอกจากนี้แผงวงจร IPST-SE ยังมีพอรตสําหรับสื่อสารขอมูลอนุกรมหรือ UART อีกหนึ่งชุด นั่นคือ UART1 ซึ่งใชพอรตหมายเลข 2 เปนขา RxD สําหรับรับขอมูลอนุกรม และพอรตหมายเลข 3 เปนขา TxD สําหรับสงขอมูลอนุกรม โดย UART1 นีใช ้ สําหรับเชือมต ่ ออุปกรณสือสารข ่ อมูลอนุกรม ทั้งแบบมีสายหรือไรสายอยางบลูทูธ หรือ XBEE ดวยระดับสัญญาณ TTL (0 และ +3.3V หรือ +5V) รวมถึงโมดูล Serial WiFi เพือช ่ วยใหแผงวงจร IPST-SE เชื่อมตอกับเครือขายอินเทอรเน็ตได อันจะ นําไปสูการพั ฒนาโครงงานควบคุมอุปกรณผานโครงขายขอมูลในแบบตางๆ รวมถึงการควบคุมขาม โลกผานเว็บบราวเซอร Serial.begin(speed)
Serial.print(data)
Serial.println(data)
Serial.write(data)
Serial.available()
Serial.read(data)
รูปที่ 3-5 กลไกการสือสารข ่ อมูลอนุกรมของฟงกชัน่ Serial ใน Arduino 1.0.x
Serial.flush()
62 Arduino IDE
3.3.1 คําอธิบายและการเรียกใชฟงกชัน่ 3.3.1.1 Serial.begin(int
datarate)
กําหนดคาอัตราบอดของการรับสงขอมูลอนุกรม ในหนวยบิตตอวินาที (bits per second : bps หรือ baud) ในกรณีที่ติดตอกับคอมพิวเตอรใหใชคาตอไปนี้ 300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600 หรือ 115200 พารามิเตอร Int datarate ในหนวยบิตตอวินาที (baud หรือ bps)
ตัวอยางที่ 3-4 void setup() { Serial.begin(9600); }
// เปดพอรตอนุกรม กําหนดอัตราบอดเปน 9600 บิตตอวินาที
3.3.1.2 Serial.available() ใชแจงวาไดรับขอมูลตัวอักษร (characters) แลว และพรอมสําหรับการอานไปใชงาน คาที่สงกลับจากฟงกชั่น จํานวนไบตทีพร ่ อมสําหรับการอานคา โดยเก็บขอมูลในบัฟเฟอรตัวรับ ถาไมมีขอมูล จะมีคาเปน 0 ถามีขอมูล ฟงกชั่นจะคืนคาที่มากกวา 0 โดยบัฟเฟอรเก็บขอมูลไดสูงสุด 128 ไบต
3.3.1.3 Serial.read() ใชอานคาขอมูลที่ไดรับจากพอรตอนุกรม คาที่สงกลับจากฟงกชั่น เปนเลข int ทีเป ่ นไบตแรกของขอมูลทีได ่ รับ (หรือเปน -1 ถาไมมีขอมูล)
ตัวอยางที่ 3-5 int incomingByte = 0; void setup() { Serial.begin(9600); } void loop() { if (Serial.available() > 0)
// เปดพอรตสือสาร ่ กําหนดอัตราบอด 9600 บิตตอวินาที // วนสงขอมูลเมือได ่ รับขอมูลเขามา // อานขอมูลอนุกรม
Arduino IDE 63
{ incomingByte = Serial.read(); // เก็บขอมูลทีอ่ านไดไวในตัวแปร Serial.print("I received: "); // พิมพขอความออกไปยังหนาตาง Serial Monitor Serial.println(incomingByte, DEC); // พิมพขอมูลทีรั่ บไดออกไปยังหนาตาง Serial Monitor } } ในตัวอยางนี้ เลือกใชอัตราบอด 9600 บิตตอวินาที ถามีขอมูลเขามาจะเก็บไวในตัวแปร incomingByte แลวนําไปแสดงผลทีหน ่ าตาง Serial Monitor โดยตอทายขอความ I received :..... เมือรั ่ นโปรแกรม ใหเปดหนาตาง Serial Monitor โดยคลิกทีปุ่ ม
ซึ่งอยูที มุ่ มขวาของหนาตางหลัก
เลือกอัตราบอดของหนาตาง Serial Monitor เปน 9600baud, เลือก No line Ending คลิกทําเครืองหมายที ่ ช่ อง Autoscroll จากนั้นปอนอักษร a แลวคลิกปุม Send
เมือแผงวงจร ่ IPST-SE ไดรับขอมูล จะสงคาของตัวอักษรในรูปของเลขฐานสิบกลับมา อักษร a มีรหัสแอสกีเท ้ ากับ 61 เมือแปลงเป ่ นเลขฐานสิบ จะไดคาเปน 97
3.3.1.4 Serial.flush() ใชลางบัฟเฟอรตัวรับขอมูลของพอรตอนุกรมใหวาง
64 Arduino IDE
3.3.1.5 Serial.print(data) ใชสงขอมูลออกทางพอรตอนุกรม พารามิเตอร Data - เปนขอมูลเลขจํานวนเต็ม ไดแก char, int หรือเลขทศนิยมทีตั่ ดเศษออกเปนเลขจํานวนเต็ม
รูปแบบฟงกชั่น คําสั่งนี้สามารถเขียนไดหลายรูปแบบ Serial.print(b)
เปนการเขียนคําสังแบบไม ่ ไดระบุรูปแบบ จะพิมพคาตัวแปร b เปนเลขฐานสิบ โดยพิมพตัวอักษรรหัส ASCII ดังตัวอยาง int b = 79; Serial.print(b); พิมพขอความ 79 Serial.print(b, DEC)
เปนคําสั่งพิมพคาตัวแปร b เปนตัวเลขฐานสิบ โดยพิมพตัวอักษรตามรหัส ASCII ดังตัวอยาง int b = 79; Serial.print(b); พิมพขอความ 79 Serial.print(b, HEX)
เปนคําสั่งพิมพคาตัวแปร b เปนตัวเลขฐานสิบหก โดยพิมพตัวอักษรตามรหัส ASCII ดังตัวอยาง int b = 79; Serial.print(b, HEX); พิมพขอความ 4F Serial.print(b, OCT)
เปนคําสั่งพิมพคาตัวแปร b เปนตัวเลขฐานแปด โดยพิมพตัวอักษรตามรหัส ASCII ดังตัวอยาง int b = 79; Serial.print(b, OCT); พิมพขอความ 117 Serial.print(b, BIN)
เปนคําสั่งพิมพคาตัวแปร b เปนตัวเลขฐานสอง โดยพิมพตัวอักษรตามรหัส ASCII ดังตัวอยาง int b = 79; Serial.print(b, BIN); พิมพขอความ 1001111
Arduino IDE 65 Serial.write(b)
เปนคําสังพิ ่ มพคาตัวแปร b ขนาด 1 ไบต เดิมทีคําสังนี ่ ้ จะเปน Serial.print(b,BYTE) ตังแต ้ Arduino 1.0 ขึนมา ้ ไดยกเลิกคําสั่ง Serial.print(b,BYTE) และใหใชคําสั่ง Serial.write(b) แทน ดังตัวอยาง int b = 79; Serial.write(b); พิมพตัวอักษร O ซึ่งมีคาตามตาราง ASCII เทากับ 79 ใหดูขอมูลจากตารางรหัสแอสกีเพิ ้ มเติ ่ ม Serial.print(str)
เปนคําสังพิ ่ มพคาขอความในวงเล็บ หรือขอความทีเก็ ่ บในตัวแปร str ดังตัวอยาง Serial.print(“Hello World!”); พิมพขอความ Hello World
พารามิเตอร b - ไบตขอมูลทีต่ องการพิมพออกทางพอรตอนุกรม str - ตัวแปรสตริงทีเก็ ่ บขอความสําหรับสงออกพอรตอนุกรม
ตัวอยางที่ 3-6 int analogValue = 0; // กําหนดตัวแปรเก็บคาสัญญาณอะนาลอก void setup() { Serial.begin(9600); // เปดพอรตอนุกรม กําหนดอัตราบอดเปน 9600 บิตตอวินาที } void loop() { analogValue = analogRead(0); // อานคาสัญญาณอะนาลอกชอง 0 // โดยตอแผงวงจร ZX-POT เขาทีจุ่ ดตอ A0 // แสดงผลทีหน ่ าตาง Serial Monitor ในหลายรูปแบบ Serial.print(analogValue); // แสดงเปนรหัสแอสกีของเลขฐานสิ ้ บ Serial.print("\t"); // คันด ่ วยแท็บ (tab) Serial.print(analogValue, DEC); // แสดงเปนรหัสแอสกีของเลขฐานสิ ้ บ Serial.print("\t"); // คันด ่ วยแท็บ (tab) Serial.print(analogValue, HEX); // แสดงเปนรหัสแอสกีของเลขฐานสิ ้ บหก Serial.print("\t"); // คันด ่ วยแท็บ (tab) Serial.print(analogValue, OCT); // แสดงเปนรหัสแอสกีของเลขฐานแปด ้ Serial.print("\t"); // คันด ่ วยแท็บ (tab) Serial.print(analogValue, BIN); // แสดงเปนรหัสแอสกีของเลขฐานสอง ้ Serial.print("\t"); // คันด ่ วยแท็บ (tab)
66 Arduino IDE
Serial.write(analogValue/4); // แสดงขอมูลดิบ ซึ่งตองผานการหารดวย 4 เนื่องจากฟงกชั่น analogRead() คืนคา 0 ถึง 1023 // แตตัวแปรแบบไบตรับคาไดเพียง 255 Serial.print("\t"); // คันด ่ วยแท็บ (tab) Serial.println(); // ขึนบรรทั ้ ดใหม delay(10); // หนวงเวลา 10 มิลลิวินาที } ตัวอยางนีแสดงการพิ ้ มพขอมูลจากฟงกชัน่ Serial.Print() ในรูปแบบตางๆ แสดงผานหนาตาง Serial Monitor
ตองเลือกอัตราบอดของหนาตาง Serial Monitor เปน 9600baud, เลือก No line Ending และคลิกทําเครื่องหมายที่ชอง Autoscroll ดวย จึงจะไดผลการทํางานทีถู่ กตอง
เทคนิคสําหรับการเขียนโปรแกรม Serial.print() จะตัดเศษเลขทศนิยมเหลือเปนเลขจํานวนเต็ม ทําใหสวนทศนิยมหายไป ทางแกไขทางหนึงคื ่ อ คูณเลขทศนิยมดวย 10, 100, 1000 ฯลฯ ขึนอยู ้ กั บจํานวนหลักของเลขทศนิยม เพื่อแปลงเลขทศนิยมเปนจํานวนเต็มกอนแลวจึงสงออกพอรตอนุกรม จากนั้นที่ฝงภาครับใหทําการ หารคาที่รับไดเพื่อแปลงกลับเปนเลขทศนิยม
Arduino IDE 67
3.3.1.6 Serial.println(data) เปนฟงกชั่นพิมพ (หรือสง) ขอมูลออกทางพอรตอนุกรมตามดวยรหัส carriage return (รหัส ASCII หมายเลข 13 หรือ \r) และ linefeed (รหัส ASCII หมายเลข 10 หรือ \n) เพือให ่ เกิดการเลื่อน บรรทัดและขึ้นบรรทัดใหมหลังจากพิมพขอความ มีรูปแบบเหมือนคําสั่ง Serial.print() รูปแบบฟงกชั่น Serial.println(b)
เปนคําสังพิ ่ มพขอมูลแบบไมไดระบุรูปแบบ จะพิมพคาตัวแปร b เปนเลขฐานสิบ ตามดวยรหัสอักษร carriage return และ linefeed ดังตัวอยางตอไปนี้ Serial.println(b, DEC)
เปนคําสั่งพิมพคาตัวแปร b เปนตัวเลขฐานสิบ ตามดวยรหัสอักษร carriage return และ linefeed Serial.println(b, HEX)
เปนคําสั่งพิมพคาตัวแปร b เปนตัวเลขฐานสิบหก ตามดวยรหัสอักษร carriage return และ linefeed Serial.println(b, OCT)
เปนคําสั่งพิมพคาตัวแปร b เปนตัวเลขฐานแปด ตามดวยรหัสอักษร carriage return และ linefeed Serial.println(b, BIN)
เปนคําสั่งพิมพคาตัวแปร b เปนตัวเลขฐานสอง ตามดวยรหัสอักษร carriage return และ linefeed Serial.println(b, BYTE)
เปนคําสั่งพิมพคาตัวแปร b ขนาด 1 ไบต ตามดวยรหัสอักษร carriage return และ linefeed Serial.println(str)
เปนคําสั่งพิมพคาขอความในวงเล็บหรือขอความ ทีเก็ ่ บในตัวแปร str ตามดวยรหัสอักษร carriage return และ linefeed Serial.println()
เปนคําสั่งพิมพรหัส carriage return และ linefeed
พารามิเตอร b - ไบตขอมูลทีต่ องการพิมพออกทางพอรตอนุกรม str - ตัวแปรสตริงทีเก็ ่ บขอความสําหรับสงออกพอรตอนุกรม
68 Arduino IDE
ตัวอยางที่ 3-7 int analogValue = 0; void setup() { Serial.begin(9600); } void loop() { analogValue = analogRead(0); // แสดงผลในรูปแบบตางๆ Serial.println(analogValue); Serial.println(analogValue, DEC); Serial.println(analogValue, HEX); Serial.println(analogValue, OCT); Serial.println(analogValue, BIN); Serial.write(analogValue); Serial.println(); Serial.flush(); delay(500);
// ประกาศตัวแปรสําหรับเก็บคาอะนาลอก // เปดพอรตอนุกรมและเลือกอัตราบอดเปน 9600 บิตตอวินาที
// อานคาอินพุตอะนาลอกชอง 0 // ตอแผงวงจร ZX-POT กับพอรตอินพุตอะนาลอก A0 // แสดงเปนรหัสแอสกีของเลขฐานสิ ้ บ // แสดงเปนรหัสแอสกีของเลขฐานสิ ้ บ // แสดงเปนรหัสแอสกีของเลขฐานสิ ้ บหก // แสดงเปนรหัสแอสกีของเลขฐานแปด ้ // แสดงเปนรหัสแอสกีของเลขฐานสอง ้ // แสดงคาในรูปแบบขอมูลระดับไบต // หนวงเวลา 500 มิลลิวินาที
}
ตองเลือกอัตราบอดของหนาตาง Serial Monitor เปน 9600baud, เลือก No line Ending และคลิกทําเครื่องหมายที่ชอง Autoscroll ดวย จึงจะไดผลการทํางานทีถู่ กตอง
Arduino IDE 69
3.4 ฟงกชันอิ ่ นพุตเอาตพุตอะนาลอก 3.4.1 ฟงกชันอิ ่ นพุตอะนาลอก analogRead(pin) อานคาจากขาพอรตที่กําหนดใหเปนอินพุตอะนาลอกของแผงวงจรหลัก IPST-SE โดยแผง วงจร IPST-SE มีวงจรแปลงสัญญาณอะนาลอกเปนดิจิตอลทีมี่ ความละเอียด 10 บิตอยูภายใน จึงแปลง คาแรงดันอินพุต 0 ถึง +5V ใหเปนขอมูลตัวเลขจํานวนเต็มระหวาง 0 ถึง 1023 พารามิเตอร pin - หมายเลขของขาอินพุตอะนาลอก มีคา 0 ถึง 5 หรือเปนตัวแปรทีใช ่ แทนคา 0 ถึง 5
คาที่สงกลับ เลขจํานวนเต็มจาก 0 ถึง 1023
หมายเหตุ สําหรับขาทีเป ่ นอินพุตอะนาลอกไมจําเปนตองประกาศแจงวาเปนอินพุตหรือเอาตพุต
ตัวอยางที่ 3-8 int ledPin = 17; // ตอแผงวงจร ZX-LED เขาทีพอร ่ ต 17 int analogPin = 0; // ตอแผงวงจร ZX-POT เขาทีพอร ่ ตอินพุต A0 int val = 0; // กําหนดตัวแปรรับคาอะนาลอก int threshold = 512; // กําหนดคาอางอิง void setup() { pinMode(ledPin, OUTPUT); // กําหนดใหพอรต 17 เปนเอาตพุต } void loop() { val = analogRead(analogPin); // อานคาอินพุตอะนาลอก A0 if (val >= threshold) { digitalWrite(ledPin, HIGH); // ขับ LED } else { digitalWrite(ledPin, LOW); // ดับ LED } } ตัวอยางนี้จะสังให ่ พอรต 17 เปนลอจิก “1” เมืออ ่ านคาจากพอรตอินพุต A0 แลวมีคามากกวาหรือเทากับ คาอางอิงทีกํ่ าหนดไว (ในตัวอยาง คาอางอิงหรือ threshold = 255) แตถานอยกวา สถานะทีพอร ่ ต 17 จะกลายเปนลอจิก “0” ทําให LED ดับ
70 Arduino IDE
3.4.2 ฟงกชันเอาต ่ พุตอะนาลอก analogWrite(pin, value) ใชเขียนคาอะนาลอกไปยังพอรตทีกํ่ าหนดไว เพือสร ่ างสัญญาณ PWM มีกระบวนการทํางาน ตามรูปที่ 3-6 พารามิเตอร pin - หมายเลขขาพอรตของแผงวงจรหลัก IPST-SE เลือกได 2 ขาคือ 19 และ 20 value - เปนคาดิวตี้ไซเกิลมีคาระหวาง 0 ถึง 255 เมือค ่ าเปน 0 แรงดันของขาพอรตทีกํ่ าหนดจะเปน 0V เมือมี ่ คาเปน 255 แรงดันที่ขาพอรตจะเปน +5V สําหรับคาระหวาง 0 ถึง 255 จะทําใหขาพอรตทีกํ่ าหนดไวมีคาแรงดันเปลียนแปลงในย ่ าน 0 ถึง +5V
คาที่สงกลับจากฟงกชั่น เลขจํานวนเต็มจาก 0 ถึง 255
หมายเหตุ ขาพอรตทีใช ่ สรางสัญญาณ PWM ดวยฟงกชั่น analogWrite() ของแผงวงจร IPST-SE มี 6 ขาคือ ขา 4, 5, 6, 7, 19 และ 20 แตจะตอออกมาเปนจุดตอเพือใช ่ งานกับอุปกรณภายนอกเพียง 2 ขาคือ พอรต 19 และ 20 สําหรับขาอื่นๆ ถูกตอเขากับวงจรขับมอเตอรบนแผงวงจร IPST-SE จึงไมสามารถทําการทดสอบคําสั่ง analogWrite ให เห็นได
ผูใชงานสามารถนําสัญญาณที่ไดจากคําสั่งนี้ไปใชในการปรับความสวางของ LED หรือตอ ขยายกระแสเพื่อตอปรับความเร็วของมอเตอรได หลังจากเรียกใชคําสั่งนี้แลวทีขาพอร ่ ตที่กําหนดจะ มีสัญญาณ PWM สงออกมาอยางตอเนือง ่ จนกวาจะมีการเรียกคําสั่ง analogWrite (หรือเรียกคําสั่ง digitalRead หรือ digitalWrite ที่ขาเดียวกัน)
analogWrite(pin, value)
รูปที่ 3-6 ไดอะแกรมแสดงกลไกการทํางานเพือสร ่ างสัญญาณ PWM ของ Arduino และแผงวงจร IPST-SE
Arduino IDE 71
ตัวอยางที่ 3-9 int ledPin = 19; int analogPin = 0; int val = 0; int threshold = 512; void setup() {} void loop() { val = analogRead(analogPin); analogWrite(ledPin, val / 4);
// ตอแผงวงจร ZX-LED เขาทีพอร ่ ต 19 // ตอแผงวงจร ZX-POT เขาทีพอร ่ ตอินพุต A0 // กําหนดตัวแปรรับคาอะนาลอก // กําหนดคาอางอิง
// เก็บขอมูลทีอ่ านไดจากอินพุตอะนาลอกลงในตัวแปร // ปรับคาที่ไดจากการแปลงสัญญาณ 0 ถึง 1023 // เปนคา 0 ถึง 255 แลวสงไปยังพอรตเอาตพุตอะนาลอก
} ตัวอยางนี้เปนการควบคุมความสวางของ LED ทีต่ อกับพอรต 19 ใหเปนไปตามคาที่อานไดจากแผงวงจร ZX-POT (แผงวงจรตัวตานทานปรับคาได) ทีต่ อกับพอรต A0
3.5 ฟงกชันพอร ่ ตอินพุตเอาตพุตขันสู ้ ง (Enhanced I/O) 3.5.1 shiftOut(dataPin, clockPin, bitOrder, value) เปนฟงกชั่นสําหรับเลื่อนขอมูลขนาด 1 ไบต (8 บิต) ออกจากขาพอรตที่กําหนดไว สามารถ กําหนดไดวา จะใหเริ่มเลื่อนบิตขอมูลจากบิตที่มีความสําคัญสูงสุด (MSB หรือบิตซายสุด) หรือบิต ที่มีความสําคัญตํ่าสุด (LSB - บิตขวาสุด) โดยบิตของขอมูลจะออกที่ขา dataPin และใชอีกหนึ่งขาคือ clockPin เปนตัวกําหนดจังหวะการเลื่อนขอมูล การสงขอมูลวิธีทีว่ านีเรี้ ยกวา การสงขอมูลอนุกรมแบบโปรโตคอลซิงโครนัส ซึงเป ่ นวิธีทัวไป ่ ทีไมโครคอนโทรเลอร ่ ใชติดตอกับตัวตรวจจับหรือไมโครคอนโทรลเลอรตัวอืน่ อุปกรณทังสองตั ้ วตอง ทํางานประสานกัน (ซิงโครไนซกัน) และติดตอกันทีความเร็ ่ วสูงสุด เนืองจากอุ ่ ปกรณทังสองตั ้ วจะใช สัญญาณนาฬิกาเดียวกัน จะเรียกชืออี ่ กอยางวา เปนการสือสารแบบ ่ SPI (synchronous peripheral interface) พารามิเตอร dataPin - พอรตทีกํ่ าหนดใหเปนเอาตพุตเพือส ่ งขอมูลออก (ตัวแปรชนิด int) clockPin - พอรตทีกํ่ าหนดใหทําหนาทีส่ งสัญญาณนาฬิกาเพือกํ ่ าหนดจังหวะการเลือนข ่ อมูลของ dataPin bitOrder - กําหนดลําดับการเลือนบิ ่ ตขอมูล เลือกไดวาเปน MSBFIRST หรือ LSBFIRST value - ไบตขอมูลทีต่ องการสงแบบอนุกรม พอรตทีเป ่ น dataPin และ clockPin จะตองกําหนดใหเปนเอาตพุตกอน ดวยการเรียกใชฟงกชัน่ pinMode
72 Arduino IDE
การเขียนโปรแกรมที่ผิดพลาดที่พบบอยของฟงกชัน่ shiftOut เนื่องจากฟงกชั่นนี้สามารถสงขอมูลไดครั้งละ 1 ไบต (8 บิต) เทานั้น ถาเปนตัวแปร int หนึง่ ตัวเก็บขอมูลขนาด 2 ไบต (16 บิต) ทําใหไมสามารถสงคาไดโดยใชคําสั่งนี้เพียงครั้งเดียว ถาสั่งเพียง ครั้งเดียว คาที่ไดจะผิดพลาด ดังตัวอยางโปรแกรมที่ผิดพลาดตอไปนี้ ตัวอยางที่ 3-10 int data; int clock; int cs; ... digitalWrite(cs, LOW); data = 500; shiftOut(data, clock, MSBFIRST, data) digitalWrite(cs, HIGH); ขอมูลทีต่ องการเลือนเท ่ ากับ 500 ดังนันจึ ้ งมีขนาด 2 ไบต (เพราะ 1 ไบตเก็บคาไดสูงสุด 256 คา) แต เนื่องจากในโปรแกรมเลือนเพี ่ ยง 1 ไบต คาที่ไดจึงเทากับ 244 เนื่องจากขอมูล 8 บิตบนของตัวแปร data มี คาเทากับ 244
ในตัวอยางที่ 3-11 เปนการแกไขโปรแกรมเพือให ่ สามารถเลื่อนขอมูลไดอยางถูกตอง ตัวอยางที่ 3-11 ในกรณีทีต่ องการเลือนบิ ่ ต MSB กอน เขียนโปรแกรมไดดังนี้ data = 500; shiftOut(data, clock, MSBFIRST, (data >> 8)); // เลือนข ่ อมูลไบตสูง shiftOut(data, clock, MSBFIRST, data); // เลือนข ่ อมูลไบตตํา่ ในกรณีทีต่ องการเลือนบิ ่ ต LSB กอน เขียนโปรแกรมไดดังนี้ data = 500; shiftOut(data, clock, MSBFIRST, data); // เลือนข ่ อมูลไบตตํา่ shiftOut(data, clock, MSBFIRST, (data >> 8)); // เลือนข ่ อมูลไบตสูง
3.5.2 unsigned
long pulseIn(pin, value)
ใชอานคาบเวลาของพัลส (ไมวาเปน HIGH หรือ LOW) ที่เกิดขึ้นที่ pin (ขาพอรตอินพุต ดิจิตอล) ที่กําหนด เชน ถากําหนด value เปน HIGH คําสั่ง pulseIN() จะรอใหขาทีกํ่ าหนดไวมีสถานะ เปน HIGH เพือเริ ่ มจั ่ บเวลา และจับเวลาตอไปจนกวาสถานะของขานั้นจะเปน LOW จึงหยุดจับเวลา คาที่ฟงกชั่นคืนกลับมาเปนคาบเวลาของพัลสในหนวยไมโครวินาที แสดงการทํางานในรูปที่ 4 - 4
Arduino IDE 73
value = HIGH
value = LOW
เริ่มการนับเวลา
หยุดการนับเวลา
เริ่มการนับเวลา
หยุดการนับเวลา
รูปที่ 3-7 การทํางานของฟงกชัน่ pulseIn คาฐานเวลาของฟงกชั่นประมาณคาไดจากการทดลอง และอาจผิดพลาดไดในกรณีที่พัลสมี ความกวางมาก ฟงกชั่นนี้ทํางานไดดีกับสัญญาณพัลสที่มีคาบเวลา 10 ไมโครวินาทีถึง 3 นาที พารามิเตอร pin - ขาพอรตทีต่ องการอานคาคาบเวลาพัลส (ตัวแปรชนิด int) value - ระดับสัญญาณทีต่ องการตรวจจับ กําหนดเปน HIGH หรือ LOW (ตัวแปรชนิด int) โดย HIGH คือ ลอจิกสูง และ LOW คือ ลอจิกตํา่
คาที่สงกลับจากฟงกชั่น คาบเวลาของพัลสในหนวยไมโครวินาที
ตัวอยางที่ 3-12 int pin = 18; unsigned long duration; void setup() { pinMode(pin, INPUT); } void loop() { duration = pulseIn(pin, HIGH); } ฟงกชั่นนี้ไมมีกลไกการหมดเวลา ถาไมมีพัลสเกิดขึ้น จะวนรอไปตลอดเวลา ทําใหโปรแกรมคางได
74 Arduino IDE
3.6 ฟงกชันเกี ่ ่ยวกับเวลา (Time) 3.6.1 unsigned
long millis()
คืนคาเปนคาเวลาในหนวยมิลลิวินาที นับตังแต ้ ไมโครคอนโทรลเลอรเริมรั ่ นโปรแกรมปจจุบัน คาทีส่ งกลับจากฟงกชัน่ คาเวลาในหนวยเปนมิลลิวินาทีตั้งแตเริมรั ่ นโปรแกรมปจจุบัน คืนคาเปน unsigned long คาตัวเลขจะเกิด การโอเวอรโฟลว (คาเกินแลวกลับเปนศูนย) เมือเวลาผ ่ านไปประมาณ 9 ชั่วโมง
ตัวอยางที่ 3-13 long time; void setup() { Serial.begin(9600); } void loop() { Serial.print(“Time: “); time = millis(); Serial.println(time); Serial.flush(); delay(1000);
// อานคาเวลา // แสดงคาเวลา
}
3.6.2
delay(ms)
เปนฟงกชันชะลอการทํ ่ างาน หรือหนวงเวลาของโปรแกรมตามเวลาทีกํ่ าหนดในหนวยมิลลิวินาที พารามิเตอร ms - ระยะเวลาทีต่ องการหนวงเวลา หนวยเปนมิลลิวินาที (1000 ms เทากับ 1 วินาที)
ตัวอยางที่ 3-14 int ledPin = 29; void setup() { pinMode(ledPin, OUTPUT); } void loop() { digitalWrite(ledPin, HIGH); delay(1000); digitalWrite(ledPin, LOW); delay(1000); }
// ตอแผงวงจร ZX-LED กับพอรต 29 // กําหนดเปนพอรตเอาตพุต // ขับ LED // หนวงเวลา 1 วินาที // ดับ LED // หนวงเวลา 1 วินาที
Arduino IDE 75
3.6.3 delayMicroseconds(us) เปนฟงกชันชะลอการทํ ่ างาน หรือหนวงเวลาของโปรแกรมตามเวลาทีกํ่ าหนดในหนวยไมโคร วินาที เพื่อใหหนวงเวลาไดอย างแมนยํา ฟงก ชั่ นนี้ จะหยุ ดการทํางานของอินเตอรรัปต ทําให การทํางานบางอยาง เชน การรับขอมูลจากพอรตอนุกรม หรือการเพิมค ่ าทีจะส ่ งกลับคืนโดยฟงกชัน่ milis() จะไมเกิดขึน ้ ดังนันควรจะใช ้ ฟงกชันนี ่ สํ้ าหรับการหนวงเวลาสันๆ ้ ถาตองการหนวงเวลานานๆ แนะนําใหใชฟงกชัน่ delay() แทน พารามิเตอร us - คาหนวงเวลาในหนวยไมโครวินาที (1000 ไมโครวินาที = 1 มิลลิวินาที และหนึงล ่ านไมโครวินาที = 1 วินาที)
ตัวอยางที่ 3-15 int outPin = 29; // ตอแผงวงจร ZX-LED กับพอรต 29 void setup() { pinMode(outPin, OUTPUT); // กําหนดเปนพอรตเอาตพุต } void loop() { digitalWrite(outPin, HIGH); // ขับ LED delayMicroseconds(50); // หนวงเวลา 50 ไมโครวินาที digitalWrite(outPin, LOW); // ดับ LED delayMicroseconds(50); // หนวงเวลา 50 ไมโครวินาที } จากตัวอยางนี้ กําหนดใหพอรต 29 ทํางานเปนเอาตพุตเพือส ่ งสัญญาณพัลสสี่เหลี่ยมที่มีคาบเวลา 100 ไมโครวินาที คําเตือน ฟงกชั่นนี้ทํางานอยางแมนยําในชวงตั้งแต 3 ไมโครวินาทีขึ้นไป ไมอาจประกันไดวา ฟงกชั่น delayMicroseconds นีจะทํ ้ างานไดอยางเทียงตรงสํ ่ าหรับคาหนวงเวลาทีตํ่ ่ากวานี้
76 Arduino IDE
3.7 ฟงกชันทางคณิ ่ ตศาสตร 3.7.1 min(x,
y)
หาคาตัวเลขที่นอยที่สุดของตัวเลขสองตัว พารามิเตอร x - ตัวเลขตัวแรก เปนขอมูลประเภทใดก็ได y - ตัวเลขตัวทีสอง ่ เปนขอมูลประเภทใดก็ได
คาที่สงกลับจากฟงกชั่น คาทีน่ อยทีสุ่ ดของตัวเลขสองตัวทีให ่
ตัวอยางที่ 3-16 sensVal = min(sensVal, 100); ตัวอยางนี้จะไดคาของ sensVal ที่ไมเกิน 100 กลับจากฟงกชั่น
3.7.2 max(x,
y)
หาคาตัวเลขที่มากที่สุดของตัวเลขสองตัว พารามิเตอร x - ตัวเลขตัวแรก เปนขอมูลประเภทใดก็ได y - ตัวเลขตัวทีสอง ่ เปนขอมูลประเภทใดก็ได
คาที่สงกลับจากฟงกชั่น คาทีมากที ่ สุ่ ดของตัวเลขสองตัวทีให ่
ตัวอยางที่ 3-17 sensVal = max(senVal, 20); จากตัวอยางนี้ คาของ sensVal จะมีคาอยางนอย 20
3.7.3 abs(x) หาคาสัมบูรณ (absolute) ของตัวเลข พารามิเตอร x - ตัวเลข
คาที่สงกลับจากฟงกชั่น x เมื่อ x มีคามากกวาหรือเทากับศูนย (x มีคาเปนบวกหรือศูนย) -x เมื่อ x มีคานอยกวาศูนย (x มีคาติดลบ)
Arduino IDE 77
3.7.4 constrain(x,
a, b)
ปดคาตัวเลขที่นอยกวาหรือมากกวาใหอยูในชวงที่กําหนด พารามิเตอร x - ตัวเลขทีต่ องการปดคาใหอยูในช วงทีกํ่ าหนด สามารถเปนขอมูลชนิดใดก็ได a - คาตํ่าสุดของชวงทีกํ่ าหนด b - คาสูงสุดของชวงทีกํ่ าหนด
คาที่สงกลับจากฟงกชั่น x เมื่อ x มีคาอยูระหวาง a และ b a เมื่อ x มีคานอยกวา a b เมือ่ x มีคามากกวา b
ตัวอยางที่ 3-18 sensVal = constrain(sensVal, 10, 150); จากตัวอยางนี้ คาของ sensVal จะอยูในชวง 10 ถึง 150
78 Arduino IDE
3.8 ฟงกชันเกี ่ ่ยวกับตัวเลขสุม 3.8.1 randomSeed(seed) ใชกําหนดตัวแปรสําหรับสรางตัวเลขสุม โดยสามารถใชตัวแปรไดหลากหลายรูปแบบ โดย ทั่วไปจะใชคาเวลาปจจุบัน (จากฟงกชั่น milis()) แตสามารถใชคาอยางอืนได ่ เชน คาที่ไดเมือผู ่ ใชกดสวิตช หรือคาสัญญาณรบกวนที่อานไดจากขาอินพุตอะนาลอก พารามิเตอร seed เปนคาตัวเลขแบบ long int
ตัวอยางที่ 3-19 long randNumber; void setup() { Serial.begin(9600); } void loop() { randomSeed(analogRead(0)); randNumber = random(300); Serial.println(randNumber); } ในตัวอยางนี้ กําหนดใหเกิดการสุมตัวเลขเมืออ ่ านคาจากอินพุตอะนาลอกชอง 0 ยานของตัวเลขสุมคือ 0 ถึง 300 เมือสุ ่ มตัวเลขแลว ใหแสดงคานั้นที่หนาตาง Serial Monitor
Arduino IDE 79
3.8.2
long random(max), long random (min,max)
ใชสรางตัวเลขสุมเสมื อน (pseudo-random numbers) เพือนํ ่ าไปใชในโปรแกรม กอนใชฟงกชัน่ นี้จะตองเรียกใชฟงกชั่น randomSeed() กอน พารามิเตอร min กําหนดคาตัวเลขสุมไม นอยกวาคานี้ (เปนออปชันเพิ ่ มเติ ่ ม) max กําหนดคาสูงสุดของตัวเลขสุม คาทีส่ งกลับจากฟงกชัน่ คืนคาเปนตัวเลขสุมในชวงทีกํ่ าหนด (เปนตัวแปร long int)
ตัวอยางที่ 3-20 long randNumber; void setup() { Serial.begin(9600); } void loop() { randomSeed(analogRead(0)); // สุมคาจากการอานคาอินพุตอะนาลอก randNumber = random(50,300); // สุมคาในชวง 50 ถึง 300 Serial.println(randNumber); Serial.flush(); delay(50); } เมือรั ่ นโปรแกรมนี้ คาที่ไดจากจะอยูในช วง 50 ถึง 300 แมวาจะปรับคาแรงดันอินพุตทีพอร ่ ต A0 เปน 0 หรือ +5V (ซึงปกติ ่ มีคา 0 ถึง 1023) ทังนี ้ เป ้ นผลมาจากฟงกชั่น random(min,max)
80 Arduino IDE
3.9 ฟงกชันเกี ่ ่ยวกับอินเตอรรัปตจากภายนอก ใชระบุวาเมือเกิ ่ ดการอินเตอรรัปตจากภายนอกจะใหโปรแกรมกระโดดไปยังฟงกชันใด ่ หรือ ถอดการระบุฟงกชั่น
3.9.1 การอินเตอรรัปต (interrupt) หรือการขัดจังหวะการทํางานของซีพียู นับเปนคุณสมบัติทีต่ องมีในไมโครคอนโทรลเลอรสมัย ใหมและเปนคุณสมบัติที่มีบทบาทสําคัญอยางมาก ในขณะที่ระบบกําลังทําการลําเลียงขวดไปตาม สายพานเพือทํ ่ าการบรรจุนํายา ้ แลวเกิดเหตุการณขวดหมด จึงตองมีการขัดจังหวะกระบวนการบรรจุ นํายาชั ้ วขณะ ่ จนกวาจะจัดหาขวดเขามาในระบบเปนทีเรี่ ยบรอย กระบวนการทํางานก็จะดําเนินตอไป จากตัวอยางดังกลาว ถาเปรียบเทียบกับโปรแกรมควบคุมของไมโครคอนโทรลเลอร ระบบ ลําเลียงขวดเพื่อบรรจุนํ้ายาเปรียบไดกับโปรแกรมหลัก เหตุการณขวดหมดคือ เงื่อนไขของการเกิด อินเตอรรัปต ที่เปนจริง ทําใหเกิดอินเตอรรัปตขึ้น การจัดหาขวดมาเพิ่มเติมเปรียบไดกับซีพียู กระโดดออกจากโปรแกรมหลักไปทํางานที่โปรแกรมยอยบริการอินเตอรรัปต เพือจั ่ ดหาขวด นั่นคือ เสร็จสิ้นการบริการอินเตอรรัปต ซีพียูก็จะกระโดดกลับมาทํางานที่โปรแกรมหลักตอไป ระบบ สายพานลําเลียงก็จะทํางานตอไปตามปกติ
3.9.2 อินพุตรับสัญญาณอินเตอรรัปต แผงวงจร IPST-SE มีอินพุตสําหรับรับสัญญาณอินเตอรรัปตจากภายนอก 3 ขาคือ INT0 ถึง INT2 ซึ่งตรงกับขาพอรต 2, 3 และ 18 ตามลําดับ ซึ่งใชงานรวมกับขา RxD, TxD (ขารับสงขอมูล อนุกรม UART1) และขาพอรตอินพุตเอาตพุตดิจิตอลปกติ
3.9.3 attachInterrupt(interrupt, function, mode) ใชระบุวา เมื่อขาอินพุตที่รับสัญญาณอินเตอรรัปตจากภายนอกมีการเปลี่ยนแปลงจะกําหนด ใหซีพียูกระโดดไปยังฟงกชันใด ่ โดยแผงวงจรหลัก IPST-SE มีขาอินพุตรับสัญญาณอินเตอรรัปตจาก ภายนอก 3 ขาคือ INT0 ถึง INT2 ซึ่งตรงกับพอรต 2,3, และ 18 ตามลําดับ ทั้งยังตรงกับพอรต UART1 ดวย (เฉพาะขา 2-RxD และขา 3 - TxD) ดังนั้น หากเลือกใชงานอินพุตอินเตอรรัปต ก็จะใชงานพอรต อนุกรม UART1 เพือติ ่ ดตออุปกรณภายนอกไมได (หากใช INT0 และ INT1) หมายเหตุ เมือเกิ ่ ดการอินเตอรรัปตขึน้ จะไมสามารถเรียกใชฟงกชั่น milis() และ delay() ได เมือเกิ ่ ดการตอบสนอง อินเตอรรัปตแลว ดังนันข ้ อมูลทีเข ่ ามาทางพอรต UART1 อาจสูญหายได
Arduino IDE 81
พารามิเตอร Interrupt - หมายเลขของชองอินพุตอินเตอรรัปต (เปน int) function - ฟงกชั่นทีจะกระโดดไปทํ ่ างานเมื่อเกิดอินเตอรรัปต ไมรับคาพารามิเตอรและไมมีการคืนคา mode - เลือกประเภทสัญญาณทีใช ่ กระตุนใหเกิดการอินเตอรรัปต LOW เกิดอินเตอรรัปตเมือขาสั ่ ญญาณเปนลอจิก “0” CHANGE เกิดอินเตอรรัปตเมือมี ่ การเปลียนแปลงลอจิ ่ ก RISING เกิดอินเตอรรัปตเมือมี ่ การเปลียนลอจิ ่ ก “0” เปน “1” FALLING เกิดอินเตอรรัปตเมือมี ่ การเปลียนลอจิ ่ ก “1” เปน “0”
ตัวอยางที่ 3-21 int pin = 17; volatile int state = LOW; void setup() { pinMode(pin, OUTPUT); attachInterrupt(0, blink, CHANGE); } void loop() { digitalWrite(pin, state); } void blink() { state = !state; } ตัวอยางนี้เลือกอินพุตอินเตอรรัปตชอง 0 กําหนดใหไปทํางานทีฟ่ งกชั่น blink เมือเกิ ่ ดอินเตอรรัปตขึน้
3.9.4 detachInterrupt(interrupt) ยกเลิกการอินเตอรรัปต พารามิเตอร Interrupt - หมายเลขของชองอินพุตอินเตอรรัปตทีต่ องการยกเลิก (คาเปน 0 ถึง 3)
82 Arduino IDE
ความรู้เกี่ยวกับภาษา C/C++ และฟังก์ชั่นของ สำ�หรับชุดกล่องสมองกล
Arduino IDE
หนังสือเล่มนี้เป็นส่วนหนึ่งของชุดกล่อง สมองกล IPST-MicroBOX Seconday Edition [SE] โดยใช้ประกอบในการเรียนรู้ และฝึกฝนเกี่ยวกับการเขียนโปรแกรม ภาษา C/C++ เพื่อน�ำมาพัฒนาโปรแกรม ส�ำหรับก�ำหนดและควบคุมการท�ำงานของ แผงวงจรต่างๆ ในชุดกล่องสมองกล IPST-MicroBOX [SE]
www.ipst-microbox.com