IPST-MicroBOX [SE] with Arduino IDE programming reference

Page 1

ความรู้เกี่ยวกับภาษา 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


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.