ใบความรูท้ ี่ 2 ฟังก์ชัน่ พนื้ ฐานของ Arduino และตัวอย่างการใช้งานคาสั่ง ทางผู้จัดทาโปรแกรม Arduino IDE ได้จัดเตรียมฟังก์ชั่นพื้นฐาน เช่น ฟังก์ ชั่นเก่ียวกับขาพอร์ตอินพุต เอาต์พตุ ดจิ ิตอล, อินพุตเอาต์ พุตอะนาลอกเป็น ต้น ดังน้ันในการเขี ยนโปรแกรมจงึ เรียกใช้ฟังก์ช่ันเหล่านี้ไดท้ ันที โดยไม่ ต้องใช้คาสั่ง #include เพ่ือผนวกไฟล์เพ่ิมเติมแต่อย่างใด นอกจากฟังก์ชั่นพื้นฐานเหล่านี้แล้ว นักพัฒนา ท่านอ่ืนๆ ที่ร่วมในโครงการ Arduino นี้ก็ได้เพ่ิมไลบรารีอื่นๆ เช่น ไลบรารีควบคมุมอเตอร์, การติดต่อกับอุปกรณ์ บัส I2C ฯลฯ ในการเรยี กใช้งานต้องเพ่ิมบรรทัด #includeเพอื่ ผนวกไฟล์ท่เี หมาะสมกอ่ นจงึ จะเรียกใช้ฟังก์ชั่นได้ 2.1 ฟงั กช์ ัน่ อินพุตเอาต์พุตดจิ ติ อล (Digital I/O) pinMode (pin, mode) ใช้ในการกาหนดให้ขาพอร์ตใดๆใหเ้ ปน็ พอรต์ ดิจิตอลอินพุต หรือ เอาต์พตุ พารามเิ ตอร์ - pin คือ ตาแหนง่ ของขาพอร์ตของบอรด์ Arduino Uno (ค่าเปน็ int) - mode คอื โหมดการทางานเป็น INPUT หรือ OUTPUT ตอ้ งใชต้ วั พิมพ์ใหญ่เทา่ นั้น ตวั อย่างการเขียนโปรแกรม int ledPin = 13; // LED connected to Di pin 13 void setup() { pinMode(ledPin, OUTPUT); // sets as output } void loop() { digitalWrite(ledPin, HIGH); // LED on delay(1000); // waits for a second digitalWrite(ledPin, LOW); // LED off delay(1000); // waits for a second } digitalWrite(pin,value)
ใชใ้ นการสัง่ งานให้ขาพอร์ตทร่ี ะบุไวม้ ีค่าสถานะเปน็ ลอจิกสูง(HIGH) หรือ “1” หรือลอจิกตา่ (LOWหรือ “0”) พารามิเตอร์ - pin คอื ขาพอรต์ ของบอรด์ Arduino Uno (ค่าเป็น int) - value คือ มคี า่ HIGH หรือ LOW ตัวอยา่ งการเขียนโปรแกรม int ledPin = 13; // LED connected to Di pin 13 void setup() { pinMode(ledPin, OUTPUT); // sets as output } void loop() { digitalWrite(ledPin, HIGH); // LED on delay(1000); // waits for 1 second digitalWrite(ledPin, LOW); // LED off delay(1000); // waits for 1 second } กาหนดใหข้ า 13 เป็น HIGH (มีลอจกิ เป็น “1”) หน่วงเวลา 1 วนิ าทีแลว้ จึงสั่งให้ขา 13 กลบั เป็นLOW (มี ลอจกิ เป็น “0”) อีกคร้ัง digitalRead(pin) ใชใ้ นการอา่ นค่าสถานะของขาพอร์ตท่รี ะบุไวว้ ่ามคี ่าเป็น HIGH หรอื LOW พารามิเตอร์ - pin คือ ขาพอร์ตทต่ี ้องการอ่านค่าซง่ึ ต้องเปน็ ขาพอรต์ ดจิ ิตอลทาให้มีค่าได้จาก 0 ถึง 13 หรือเปน็ ตัว แปรทมี่ คี ่าอยู่ในชว่ ง 0 ถึง 13 ก็ได้ คา่ ทส่ี ่งกลบั จากฟังก์ช่นั เป็น HIGH หรอื LOW
ตวั อยา่ งการเขยี นโปรแกรม int ledPin = 13; // LED connected to Di pin 13 int inPin = 7; // pushbutton connected to digital pin 7 int val = 0; // variable to store the read value void setup() { pinMode(ledPin, OUTPUT); // sets Di 13 as output pinMode(inPin, INPUT); // sets Di 7 as input } void loop() { val = digitalRead(inPin); // read input pin digitalWrite(ledPin, val); // sets the LED to the button’s value } กาหนดให้ขา 7 เป็นอนิ พุตสถานะของ LED ทข่ี า 13 จะเปล่ียนแปลงตามสถานะของอินพุตขา 7 การทดลองใชง้ านพอร์ตเอาต์พุตดิจิตอลของ บอร์ด Arduino Uno คณุ สมบตั ขิ องขาพอรต์ เอาต์พุต สาหรับขาพอรต์ ที่กาหนดให้เปน็ เอาต์พุตผ่านทางฟังกช์ ั่น pinMode() จะมสี ถานะเปน็ อิมพแี ดนซ์ตา่ ทาให้ สามารถจา่ ยกระแสให้กับวงจรภายนอกได้สูงถงึ 20mA ซึง่ เพียงพอสาหรับขับกระแสให้ LED สวา่ งได้ (อย่าลืมตอ่ ตัวต้านทานอนุกรมด้วย) หรอื ใชก้ ับตัวตรวจจับตา่ งๆ ไดแ้ ตไ่ ม่เพยี งพอสาหรับขับรีเลย์โซลนี อยดห์ รือมอเตอร์ ก่อนทจี่ ะใช้งานขาดจิ ิตอลของบอรด์ Arduino Uno จะต้องสง่ั ก่อนวา่ ให้ใดทาหนา้ ทีเ่ ป็นอินพุตหรือ เอาต์พุตในหัวข้อน้จี ะทดลองต่อเป็นเอาต์พุตถา้ กาหนดใหเ้ ปน็ เอาต์พุต การกาหนดโหมดการทางานของขาพอร์ต ก่อนใช้งานต้องกาหนดโหมดการทางานของขาพอรต์ ดิจติ อลให้เปน็ อินพตุ หรือเอาต์พุตกาหนดได้จาก ฟงั กช์ ั่น pinMode()มรี ูปแบบดังนี้ pinMode(pin,mode);
เมอื่ pin คอื หมายเลขขาทีต่ ้องการ Mode คือ โหมดการทางาน (INPUT หรอื OUTPUT) หลงั จากท่ีกาหนดให้เป็นเอาต์พุตแล้วเมอื่ ตอ้ งการเขยี นค่าไปยังขาน้นั ๆใหเ้ รียกใชฟ้ ังกช์ ั่น digitalWrite() โดยมรี ปู แบบดังน้ี digitalWrite(pin,value); เมอื่ pin คอื หมายเลขขาทีต่ ้องการ value สถานะลอจกิ ทตี่ ้องการ (HIGH หรอื LOW) ตวั อย่างโปรแกรมสงั่ ให้ LED กะพริบ ในการทดลองเก่ียวกับไมโครคอนโทรลเลอร์เร่ืองแรก ก็คือการสั่งให้พอร์ตทางานเป็นเอาต์พุตและสั่งให้มี ค่าเป็น HIGH หรือ LOW ได้ตามที่ต้องการโดยจะตอ่ กับ LED และสั่งให้ LED ตดิ ดับต่อเน่ืองกันตลอดเวลาเรียกว่า ไฟกะพริบ ในการทดลองขับ LED อย่างง่ายได้ยกตัวอย่างไฟล์ Blink ซึ่งมีตัวอย่างในโปรแกรมArduino IDE อยู่ แลว้ ในตัวอย่างนี้จะนาโปรแกรม Blink.ino มาประยุกต์สั่งเอาต์พุตของบอร์ด Arduino Uno ควบคุม LED สองดวงใหต้ ิดดบั สลบั กนั เริ่มต้นด้วยการต่อวงจรส่วนของ LED ดังรูปที่ 4-1 (ก) ในรูปจะต่อวงจรให้ LED ทางานท่ีลอจิก 1 คือเมื่อส่ังให้ขา เป็น HIGH จะทาให้ LED ตดิ เมอ่ื สั่งให้ขาเปน็ LOW หลอดจะดบั ดงั รปู เมือ่ ต่ออปุ กรณ์แล้วใหเ้ ขยี นโปรแกรมตามรูปแล้วทาการคอมไพล์และอปั โหลดลงบอรด์ Arduino Uno เพือ่ ศึกษาผลการทางาน
ในโปรแกรมตัวอย่าง บรรทัด #define LED1_PIN 11 คือการกาหนดค่าคงที่ให้ข้อความLED1_PIN มีค่า เท่ากับ 11 หลังจากบรรทัดน้ีในโปรแกรมเม่ือพบข้อความ LED1_PIN ให้นาค่า 11 ไปแทนท่ีแล้วจึงคอมไพล์ โปรแกรม เม่ือโปรแกรมทางานได้แล้วทดลองแก้ไขโปรแกรมเพ่ือเปล่ียนตาแหน่งขาเอาต์พุตท่ีต่อกับ LED โดย เปล่ยี นค่าตวั เลขของบรรทัด #define LED1_PIN 11 เปน็ ค่าอน่ื ๆ ระหว่าง 2 ถึ ง 12 บรรทั ด delay(1000); เป็นการเรียกใช้ฟังก์ชั่น delay() โดยส่งค่า 1000 ให้กับฟังก์ชั่นเพ่ือให้เกิดการ หน่วงเวลา 1000 มิลลิวินาที (ms) หรือ 1 วินาทีถ้าต้องการปรับให้ LED กะพริบเร็วข้ึนหรือช้าลงสามารถเปลี่ยน ค่าในวงเล็บเป็นคา่ อ่ืนๆ ได้โดยค่ายิง่ มาก LED ยิ่งกะพรบิ ช้าลง การทดลองอนิ พตุ ดิจติ อลของบอร์ด Arduino Uno คุณสมบัตขิ องขาพอรต์ อินพุต ขาพอร์ตของบอร์ด Arduino Uno จะถูกกาหนดเป็นอินพุตต้ังแต่เริ่มต้น จึงไม่จาเป็นต้องใช้ฟังก์ชั่น pinMode() ในการกาหนดให้เป็น ขาพอร์ตที่ถูกกาหนดเป็นอินพุตจะมีสถานะเป็นอิมพีแดนซ์สูง ทาให้มีความ ต้องการกระแสไฟฟ้าจากอุปกรณ์ที่ต้องการอ่านค่าอินพุตน้อยมาก ทาให้ไม่สามารถทาให้ไม่สามารถรับหรือจ่าย กระแสไฟให้กับวงจรภายนอกทาให้นาขาที่เป็นอินพุตน้ีไปใช้งานบางประเภทเช่น สร้างตัวตรวจจับการสัมผัสที่ อาศัยการวัดคา่ ความจุไฟฟ้า สาหรับขาอินพุตเม่ือไม่มีอินพุตป้อนให้จะต้องกาหนดค่าแรงดันให้แน่นอนทาได้โดยต่อตัวต้านทานพูลอัป (pull-up resistor) โดยต่อขาของตัวต้านทานขาหนึ่งไปยังไฟเล้ียงหรือต่อพูลดาวน์ (pull- down) ซึ่งต่อขาหน่ึง ของตัวตา้ นทานจากขาพอรต์ ลงกราวดค์ า่ ตวั ตา้ นทานท่ีใชท้ ั่วไปคือ 10kΩ ดังรูป
บอร์ด Arduino Uno มีขาพอร์ตดิจิตอลที่กาหนดให้เป็นอินพุตหรือเอาต์พุตจานวน 14 ขา ถ้าต้องการ กาหนดเป็นอินพุตต้องกาหนดด้วยฟังก์ชั่น pinMode และอ่านค่าอินพุตได้จากฟังก์ชั่น digitalRead ซึ่งมีรูปแบบ ดังนี้ digitalRead(pin); เมอื่ pin คอื หมายเลขขาท่ีต้องการอ่านคา่ สถานะ เมื่อฟังก์ช่ันทางานจะคืนค่าเป็นสถานะของขาที่ต้องการอ่านค่าโดยคืนค่าเป็น LOW (ค่าเป็ น “0”)หรือ HIGH (ค่าเปน็ “1”) ภายในขาพอร์ตของไมโครคอนโทรลเลอร์ ATmega32U4 ซึ่งเป็นไมโครคอนโทรลเลอร์หลักของบอร์ด Arduino Uno จะมีการตอ่ ตัวต้านทานพูลอัปค่า 20kΩ เตรยี มไว้ใหซ้ ่ึงสามารถส่งั ตอ่ ใชง้ านผ่านทางซอฟต์แวร์ดงั ใน รปู สาหรบั ตัวอยา่ งโปรแกรมเพื่อใช้งานมดี งั น้ี pinMode(pin, INPUT); // set pin to input digitalWrite(pin, HIGH); // turn on pullup resistors ทดลองรบั คา่ สวิตช์อยา่ งง่าย
ในการทดลองนี้จะทดลองอ่านค่าสถานะของสวติ ชแ์ บบกดตดิ ปลอ่ ยดบั เพอ่ื ควบคุมหลอด LED เมอ่ื กด สวิตช์ S1 ทาให้ LED1ตดิ สวา่ งเม่ือปล่อยสวิตช์ LED1 จะดับโดยมีวงจรแสดงไดด้ งั รปู ในการใช้งานขาอินพุตดิจติ อลตอ้ งต่อตัวต้านทานพูลอัป (ตอ่ ตัวตา้ นทานจากไฟเล้ียง +5V มายังขาอินพุต) เพื่อกาหนดสถานะที่แน่นอนให้กับขาอินพุตในภาวะท่ีไม่มีการกดสวิตช์ ดังวงจรในรูปท่ี 4-5 โดยต่อขา 7 ผ่านตัว ต้านทานค่า 10kΩ ไปยังไฟเลี้ยง +5V เม่ือไม่ได้กดสวิตช์ SW1 ที่ขา 7 จะมีสถานะเป็นลอจิกสูงหรือ HIGH หรือ “1” เมื่อกดสวิตช์จะทาให้ขา 7 ต่อลงกราวด์อา่ นค่าสถานะเป็นลอจิกต่าหรือ LOW หรือ “0” เมื่อต่ออุปกรณ์แล้ว ใหเ้ ขียนโปรแกรมตามรูปแลว้ ทาการคอมไพลแ์ ละอปั โหลดลงบอร์ด Arduino Uno เพอื่ ศึกษาผลการทางาน
การทางานของ LED1 จะตรงข้ามกับสถานะของสวิตชค์ อื เมอื่ ไม่กดสวติ ช์จะอา่ นสถานะของขา 7 ได้ลอจิก สูงจึงต้องส่ังให้ขา 11 เป็นลอจิกต่าหรือ “0” เพื่อทาให้ LED1 ดับ เม่ือกดสวิตช์อ่านค่าสถานะของขา 7ได้ลอจิก “0” ตอ้ งสัง่ ใหข้ า 11 เปน็ “1” เพ่ือขบั LED1 ติดสว่าง เม่ือโปรแกรมทางานได้ผลตามท่ีต้องการแล้วให้ทดลองถอดตัวต้านทานพูลอัปค่า10kΩ ออก เพื่อให้ขา7 ลอย สังเกตกรณีน้เี มือ่ ยังไม่มีการกดสวิตช์ LED1 อาจติดกะพริบด้วยความเร็วสงู เห็น LED สว่างเรื่อยๆ เนอื่ งจาก สถานะของขา Di7 เป็น “0” และ “1” สลับกนั ไมแ่ น่นอน การแกป้ ญั หาสัญญาณรบกวนในการกดสวติ ซ์โดยใช้ซอฟต์แวร์ ในหัวข้อน้ีจะทดลองเขียนโปรแกรมรับค่าของสวิตซ์ซ่ึงเป็นแบบกดติดปล่อยดับ ให้มีการทางานแบบกด ติดกดดับคือ เม่ือเร่ิมต้นโปรแกรม LED ดับอยู่ เม่ือกดสวิตซ์ LED จะติดสว่าง เมื่อกดสวิตซ์อีกคร้ัง LED จะดับ สลับกันไปมาตลอดเวลา โดยวงจรท่ใี ชย้ ังเป็นวงจรในการทดลองที่ผา่ นมา โดยท่ัวไปแล้วสวิตซ์ท่ีใช้จะเป็นสวิตซ์ทางกลท่ีประกอบด้วยหน้าสัมผัสโลหะ ในการกดสวิตซ์ให้ต่อวงจร พบว่าหน้าสัมผัสของสวิตซ์จะไม่สัมผัวกันสนิททันที โดยมีช่วงเวลาท่ีเร่ิมสัมผัสและหลุดเป็นช่วงเวลาสั้นๆ ก่อนที่ หนา้ สัมผสั ของสวิตซจ์ ะต่อย่างสมบรู ณ์ และเมื่อวัดสัญญาณทไ่ี ดจ้ ากสวติ ซ์พบว่าระดบั สัญญาณ
มีการส่ันที่เรียกว่าเบาซ์(bounce) อยู่ชั่วขณะดังแสดงในรูป โดยระยะเวลาท่ีสัญญาณเกิดการเบาซ์นี้มี ระยะเวลาต้งั แต่ไม่กม่ี ิลลิวินาที(ms) ไปจนถึงหลายสบิ มิลลวิ ินาทขี นึ้ กับประเภทของสวติ ซท์ ีใ่ ช้ การแก้ปัญหาท่ีระดับสัญญาณเกิดการส่ันนี้ เรียกว่า การดีเบาซ์(debounce)หลักการแก้ไขสัญญาณ รบกวนแบบนี้คือ หน่วงเวลาการเกิดขึ้นของสัญญาณพัลล์เล็กน้อย เพ่ือให้วงจรไม่สนใจวัญญาณท่ีเกิดข้ึนในช่วง เร่มิ ต้นกดสวติ ซ์ซ่ึงทาได้หลายวิธี เช่น วิธีการแรกทาได้โดยใช้อุปกรณ์อิเล็กทรอนิกส์พื้นฐานอย่างตัวต้านทานและตัวเก็บประจุโดยต่อกันใน ลักษณะวงจร RC อินติเกรเตอร์ดงั ในรูป ดว้ ยวิธกี ารน้ีจะช่วยลดผลของสญั ญาณรบกวนที่เกิดข้ึนจากการกดสวิตช์ได้ในระดับหนง่ึ โดยประสิทธิ
ภาพของวงจรจะข้ึนกับการเลือกค่าของตัวต้านทานและตัวเก็บประจุหากเลือกค่าของตัวเก็บประจุน้อยเกินไปอาจ ไม่สามารถลดสัญญาณรบกวนได้แต่ ถ้าเลือกค่ามากเกินไปจะทาให้ความไวในการตรวจจับการกดสวิตช์ลดลงน่ัน คอื อาจต้องกดสวติ ช์มากกว่า 1 ครัง้ เพื่อให้ไดส้ ัญญาณทต่ี อ้ งการ วิธีการที่สองแก้โดยใช้ไมโครคอนโทรลเลอร์ จะสามารถแก้ไขได้กระบวนการทางซอฟต์ แวร์โดยเขียน โปรแกรมให้ตรวจจับการเปลี่ยนแปลงระดับลอจิกของสวิตช์ ถ้าพบว่ามีการเร่ิมกดสวิตช์ก็คือระดับลอจิกเปล่ียน จาก “1” เป็น “0” โปรแกรมจะหนว่ งเวลารอจนเลยชว่ งเวลาเกิดเบาซ์ของสวิตช์เม่อื เลยเวลาแล้วให้ทาการอ่านค่า สถานะของสวิตช์อีกครั้งถ้ายังคงเป็น “0” แสดงว่ากดสวิตช์สมบูรณ์แล้ว โดยระยะเวลาท่ีต้องหน่วงเวลาหาได้จาก การใช้ออสซิลโลสโคปวัดระดับสัญญาณหรือใช้การทดลองป้อนค่าหน่วงเวลาแล้วปรับค่าจนกระทั่ งได้ค่าท่ี แก้ปัญหาการเบาวซ์ของสวิตช์ได้อย่างสมบูรณ์ในโปรแกรมทดลองที่ 4-5 ได้ทดลองโดยใช้ค่าของการหน่วงเวลา เทา่ กับ 10 มิลลวิ นิ าทซี ึ่งสามารถเปล่ี ยนได้ท่บี รรทดั #defineDEBOUNCE 10 เม่ือต่ออุปกรณ์แล้วให้เขียนโปรแกรมตามรูปแล้วทาการคอมไพล์และอัปโหลดลงบอร์ด Arduino Uno เพอื่ ศกึ ษาผลการทางาน เมื่อรันโปรแกรม LED จะเปลี่ยนสถานะเปน็ ตรงข้ามในทุกครั้งท่กี ดสวิตช์ 2.2 ฟังกช์ ่ันเกยี่ วกับการสื่อสารผ่านพอรต์ อนกุ รม
ใช้สาหรับส่ือสารข้อมูลระหว่างฮาร์ดแวร์ Arduino กับคอมพิวเตอร์หรืออุปกรณ์อ่ืนๆ โดยจะแบ่งพอร์ต สาหรับเช่ือมต่อออกเป็น 2 ส่วนคือ ส่วนแรกติดต่อพอร์ตอนุกรมเสมือน(virtual COM port) จากการทางานของ ส่วนเชื่อมต่อพอร์ต USB ฟังก์ชั่นที่ใช้คือ Serial อีกส่วนหน่ึงคือขาพอร์ตสื่อสารข้อมูลอนุกรมโดยใช้ขา0 (RxD) และ 1 (TxD) ฟงั ก์ชั่นของ Arduino Uno ที่ใช้คือ Serial1 ดงั นน้ั เมอื่ เลือกใชง้ านเป็นขาพอร์ตส่ือสารข้อมูลอนุกรม แลว้ จะไม่สามารถใชข้ าพอรต์ 0 และ 1 เปน็ พอรต์ ดจิ ติ อลได้ Serial.begin(int datarate) เป็นการเร่ิมต้นใช้งานฟังก์ช่ันการสือสารข้อมูลอนุกรม พร้อมทั้งกาหนดค่าอัตราบอดของการรับส่งข้อมูล อนุกรมในหน่วยบิตต่อวินาที (bits per second : bps) ใช้ค่าต่อไปน้ี 300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600 หรอื 115200 พารามิเตอร์ - Int datarate คือ ความเรว็ ในการสง่ ข้อมูลในหน่วยบิตต่อวินาที (baud หรือ bps) ตวั อยา่ งการเขียนโปรแกรม void setup() { Serial.begin(9600); // opens serial port, baudrate 9600 bps } เปน็ การเลอื กอัตราบอดเท่ากับ 9600 บิตต่อวินาที Serial.available() ใช้ในการตรวจสอบว่าได้รับข้อมูลตัวอักษร (characters) แลว้ และพร้อมสาหรับการอา่ นไปใช้ งาน คา่ ที่ส่งกลับจากฟังก์ชั่น จานวนไบตท์ ีพ่ ร้อมสาหรบั การอ่านคา่ โดยเก็บข้อมลู ในบัฟเฟอรต์ วั รบั ถ้าไม่มขี ้อมูลจะมคี ่าเป็น 0 ถา้ มี ข้อมูลฟังกช์ ัน่ จะคืนค่าท่ีมากกวา่ 0 โดยบัฟเฟอร์ สามารถเก็บข้อมลู ไดส้ งู สุด 128 ไบต์ int incomingByte = 0; // for incoming serial data void setup() { Serial.begin(9600); // opens serial port, baud rate 9600 bps delay(5000);
ในตัวอย่างน้ีใช้อัตราบอด 9,600 บิตต่อวินาทีเมื่อรันโปรแกรมจะต้องเปิดหน้าต่าง Serial Monitorเพื่อ ปอ้ นข้อมูลมายังบอร์ด Arduino Uno ด้วยถ้ามขี ้อมูลเข้ามาจะเกบ็ ไว้ในตวั แปร incomingByte แล้วนาไปแสดงท่ี หนา้ ตา่ ง Serial Monitor โดยต่อทา้ ยขอ้ ความ I received : คา่ ท่แี สดงจะเปน็ ค่าขอ้ มลู ในรูปของเลขฐานสบิ ยกตัวอย่างหากป้อนเลข 2 เข้ามาจะแสดงข้อความ I received : 50 เนื่องจากรหัสแอสกี้ของ 2 คือ 32 ฐานสบิ หกเทา่ กบั 50 ฐานสบิ Serial.read() ใช้อ่านคา่ ขอ้ มลู ทีไ่ ด้รับจากพอรต์ อนุกรม คา่ ท่สี ง่ กลบั จากฟังก์ชั่น เป็นเลข int ทเ่ี ป็นไบต์แรกของข้อมลู ทีไ่ ดร้ ับ (หรือเป็น -1 ถา้ ไม่มีขอ้ มูล) ตัวอยา่ งการเขยี นโปรแกรม
int incomingByte = 0; // for incoming serial data void setup() { Serial.begin(9600); // opens serial port, baud rate 9600 bps delay(5000); } void loop() { if (Serial.available() > 0) // send data only when you receive data: { incomingByte = Serial.read(); // read the incoming byte: Serial.print(\"I received: \"); // say what you got: Serial.println(incomingByte, DEC); } } Serial.flush() ใชล้ ้างบฟั เฟอร์ตวั รับข้อมลู ของพอรต์ อนุกรมให้วา่ ง 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 Serial.print(b, BYTE) เป็นคาสงั่ พิมพ์คา่ ตวั แปร b ขนาด 1 ไบต์ดงั ตวั อยา่ ง int b = 79; Serial.print(b, BYTE); พิมพ์ตวั อกั ษร O ซง่ึ มีค่าตามตาราง ASCII เทา่ กับ79 ดูขอ้ มลู จากรหัสแอสกีเ้ พ่ิมเตมิ Serial.print(str)
เป็นคาสงั่ พิมพ์ค่าข้อความในวงเลบ็ หรือข้อความท่เี ก็บในตัวแปร str ดังตวั อยา่ ง Serial.print(“Hello World!”); พิมพข์ ้อความ Hello World พารามิเตอร์ - b คือ ไบต์ข้อมลู ท่ตี ้องการพิมพ์ออกทางพอรต์ อนุกรม - str คือ ตัวแปรสตรงิ ทเ่ี ก็บข้อความสาหรับสง่ ออกพอรต์ อนุกรม ตวั อย่างนี้แสดงการพิมพ์ข้อมูลจากฟังกช์ ่ัน Serial.Print() และ Serial.write() ในรูปแบบต่างๆ แสดงผ่าน ทางหนา้ ต่าง Serial Monitor เทคนิคสาหรบั การเขียนโปรแกรม
คาส่ัง Serial.print() จะตัดเศษเลขทศนิยมเหลือเป็นเลขจานวนเต็มทางแก้ไขทางหน่ึงคือคูณเลขทศนิยม ด้วย10,100,1000 ฯลฯ ขึ้นอยู่กับจานวนหลักของเลขทศนิยมเพ่ือแปลงเลขทศนิยมเป็นจานวนเต็มก่อนแล้วจึง ส่งออกพอรต์ อนกุ รม จากนัน้ ทฝี่ ่ังภาครับให้ทาการหารคา่ ทีร่ ับไดเ้ พือ่ แปลงกลับเปน็ เลขทศนิยม Serial.println(data) เปน็ ฟังกช์ ่ันพิมพ์ (หรอื ส่ง) ขอ้ มูลออกทางพอร์ตอนุกรมตามด้วยรหัส carriage return (รหสั ASCII หมายเลข 13 หรือ \\r) และ linefeed (รหัส ASCII หมายเลข 10 หรือ \\n) เพอ่ื ให้เกดิ การเลอ่ื นบรรทดั และข้ึน บรรทดั ใหมห่ ลังจากพิมพ์ข้อความมรี ูปแบบเหมือนคาสั่ง Serial.print() รปู แบบฟงั ก์ชั่น Serial.println(b) เป็นคาสง่ั พมิ พข์ ้อมูลแบบไม่ได้ระบุรปู แบบจะพิมพ์คา่ ตัวแปรเปน็ เลขฐานสบิ ตามดว้ ยรหัสอักษร carriage return และ linefeed Serial.println(b, DEC) เป็นคาสั่งพมิ พ์คา่ ตวั แปร b เปน็ ตวั เลขฐานสิบตามดว้ ยรหสั อักษร carriage return และ linefeed Serial.println(b, HEX) เปน็ คาสง่ั พมิ พค์ า่ ตวั แปร b เปน็ ตัวเลขฐานสบิ หกตามด้วยรหัสอกั ษร carriage return และ linefeed Serial.println(b, OCT) เปน็ คาสงั่ พิมพ์ค่าตัวแปร b เปน็ ตวั เลขฐานแปดตามดว้ ยรหัสอกั ษร carriage return และ linefeed Serial.println(b, BIN) เปน็ คาสั่งพิมพค์ ่าตวั แปร b เปน็ ตวั เลขฐานสองตามดว้ ยรหสั อกั ษร carriage return และ linefeed Serial.println(str) พิมพ์คา่ ในวงเลบ็ หรอื ขอ้ ความที่เก็บในตัวแปร str ตามดว้ ยรหัสอักษร carriage return และ linefeed Serial.println() เปน็ คาสั่งพิมพ์รหัส carriage return และ linefeed พารามิเตอร์ - b คอื ไบต์ข้อมลู ท่ีต้องการพิมพ์ออกทางพอร์ตอนุกรม - str คือ ตวั แปรสตริงท่ีเก็บข้อความสาหรับสง่ ออกพอรต์ อนุกรม
การทดลองใช้งาน UART เพื่อตดิ ต่อกับคอมพวิ เตอร์ บอร์ด Arduino Uno ติดต่อกับคอมพิวเตอร์เพื่อสื่อสารข้อมูลอนุกรมผ่านพอร์ต USB โดยใช้พอร์ต อนุกรมเสมอื นหรือ virtual COM port ท่ีเกดิ ข้ึนจากการทางานของส่วนเช่ือมต่อพอร์ต USB ของบอรด์ Arduino Uno และไดรเวอร์โดยปกติแล้วจะเชื่อมต่อพอร์ตอนุกรมเสมือนผ่านทางพอร์ต USB เพ่ือติดต่อกับคอมพิวเตอร์ใน การอัปโหลดโปรแกรมเปน็ หลักแต่ก็นามาใชร้ บั ส่งข้อมูลจากโปรแกรมของผใู้ ชง้ านกับคอมพวิ เตอร์ได้ ฟงั ก์ชัน่ ท่เี กี่ยวข้องกับการรับส่งข้อมูลผ่านพอรต์ อนกุ รม Arduino มีฟงั ก์ชั่นเก่ียวกับการรบั สง่ ขอ้ มูลผา่ นพอร์ตอนุกรมมาพร้อมใช้ งานดังนี้ - Serial.begin(speed) ใชก้ าหนดอตั ราเรว็ ของการถา่ ยทอดข้อมลู หรืออัตราบอดหรือบอดเรต - Serial.available() ใชต้ รวจสอบวา่ มีข้อมูลด้านรบั เข้ามาหรอื ไมโ่ ดยคนื ค่าเปน็ int ตามจานวน ไบตข์ ้อมลู ทรี่ ับเขา้ มา - Serial.read(data) ใชอ้ า่ นค่าขอ้ มลู จากพอร์ตอนกุ รม - Serial.write(data) ใชเ้ ขยี นขอ้ มลู ไบต์ไปยังพอรต์ อนุกรม - Serial.flush() ใชล้ ้างบัฟเฟอร์ทง้ั ด้านรับและสง่ - Serial.print(data) ใชส้ ่งข้อมูลออกพอรต์ อนุกรม - Serial.println(data) ใช้ส่งข้อมลู ออกพอรต์ อนุกรมพร้อมกบั ขึ้นบรรทัดใหม่
ตัวอย่างโปรแกรมส่งข้อมลู ออกพอร์ตอนุกรม เรมิ่ ต้นด้วยการใช้ฟังก์ชั่น Serial.begin() เพือ่ ส่ังเปิดพอรต์ อนุกรมและกาหนดอัตราถ่ายทอดข้อมูลทใ่ี ชใ้ น การส่อื สารข้อมูลหรอื อัตราบอดมีรูปแบบการเขยี นโปรแกรมดังนี้ Serial.begin(speed); เมื่อ speed คืออัตราบอดมีค่า 300, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400,57600 หรือ 115200 บติ ตอ่ วินาทปี กติท่ีใชค้ ือ 9600 หลังจากเปิดพอร์ตเม่ือต้องการส่งข้อมูลให้ใช้ฟังก์ชั่น Serial.print() หรือ Serial.println() ฟังก์ชั่นท้ังสอง ตวั ทางานใหผ้ ลคล้ายกัน ต่างกนั เมอื่ ฟงั ก์ชน่ั Serial.println() สง่ ขอ้ มูลแล้วจะขึน้ บรรทดั ใหม่ให้อัตโนมัติ ฟงั กช์ ั่น Serial.print()และ Serial.println() มีรปู แบบดังนี้ Serial.print(b,FORMAT); และ Serial.println(b,FORMAT); โดยท่ี b คือค่าตัวแปรประเภทเลขจานวนเต็มท่ีต้องการส่งออกทางพอร์ตอนุกรม ถ้าไม่ระบุรูปแบบจะ พิมพอ์ อกเปน็ รหัส ASCII ของค่าตวั แปร FORMAT เป็นรูปแบบของการพิมพ์มี DEC (เลขฐานสิบ), HEX (เลขฐานสิบหก), OCT (เลขฐานแปด) และ BIN (เลขฐานสอง) ตัวอย่าง โปรแกรมทดสอบการสง่ ข้อมูลออกพอร์ตอนุกรมเสมือนผา่ นทางพอร์ต USB ของบอร์ด Arduino Uno จากโปรแกรมเป็นการทดลองสง่ ข้อมลู ออกพอร์ตอนกรุ มโดยส่ง ขอ้ ความและค่าของตัวแปรในการทดลอง ส่งคา่ ตวั แปรจะมีการกาหนดรปูแบบหรือ FORMAT ของคาสัง่ Serial.print() ไวห้ ลายๆ แบบ
ในการทดสอบการทางานโปรแกรม Arduino IDE จะมีหน้าต่าง Serial Monitor เพ่อื อานวยความสะดวก ในการรบั และส่งข้อมลู ผ่านพอรต์ อนกุ รมซึ่งจะใช้พ้ืนท่ีรว่ มกับพื้นท่ีแสดงข้อมลู (Text area) ซ่ึงอยู่ทาง ดา้ นลา่ งของหนา้ ต่างโปรแกรม Arduino การเปดิ หน้าตา่ งนที้ าได้โดยคลิกทป่ี มุ่ Serial Monitor ดังแสดงในรปู ผลการทางานของโปรแกรม หลังจากที่อัปโหลดโปรแกรมไปยังบอร์ด Uniconในโปรแกรมกาหนดค่าตัว แปร data=2345 ซ่ึงก็คือ 2,345 แปลงเป็นเลขฐาน 16 คือ 929 เป็นเลขฐาน8 คื อ 4451 เป็นเลขฐานสองคือ 100100101001 กรณีท่ีส่ังพิมพ์โดยใช้คาส่ังSerial.write(data); จะส่งค่าเป็นเลขฐานสอง 8 บิตล่าง 00101001 ซ่ึงก็คือ 41 ฐานสิบเทียบเป็นรหัส ASCII คืออักขระ ) ที่หน้าต่างของSerial Monitor จึงแสดงเป็นเคร่ืองหมาย ) หรือวงเลบ็ ปดิ น่นั เอง
ตวั อย่างโปรแกรมรับค่าจากพอร์ตอนุกรมเพ่ือกาหนดความเร็วในการกระพรบิ ของ LED ในการรับค่าจากพอร์ตอนุกรมจะใช้ฟังก์ช่ัน 2 ตัวคือ Serial.avaliable() และ Serial.read() โดยเร่ิมจาก ใช้ฟังก์ช่ัน Serial.avaliable()เพ่ือตรวจสอบว่ามีข้อมูลหรือไม่ฟังก์ชั่นจะคืนค่าเป็นเลขจานวนเต็มแสดงจานวน ขอ้ มูลในบฟั เฟอรต์ ัวรบั ของพอร์ตอนุกรมถ้าอา่ นค่าได้เทา่ กับ 0 แสดงวา่ ไมม่ ขี ้อมูล เมื่อทดสอบพบว่าฟังก์ชั่น Serial.avaliable() คืนค่าไม่เท่ากับ 0 ถัดมาให้ใช้ฟังก์ชั่นSerial.read() เพื่อ อ่านค่าจากบัฟเฟอร์ตัวรับฟังก์ช่ันคืนค่าเป็นเลขจานวนเต็มที่เป็นไบต์แรกของข้อมูลที่ได้รับ (หรือเป็น -1 ถ้าไม่มี ขอ้ มูล) ในตัวอย่างนี้แสดงตัวอย่างการรับค่าจากพอร์ตอนุกรมเพ่ือนาค่าท่ีรับได้ ไปควบคุมอัตราการกระพริบของ LED วงจรและโปรแกรมท่ีใชใ้ นการทดลองนี้แสดงได้ดงั รูป
มีส่วนของโปรแกรมที่ควรทราบอยู่แห่งหนึ่งคือหากผู้พัฒนาโปรแกรมต้องการให้มีการแสดงข้อความบน หน้าต่าง Serial monitor ของ Arduino ในทุกคร้ังที่เร่ิมต้นทางานใหม่จะต้องหน่วงเวลารอให้วงจร USB ภายใน เตรียมความพร้อมในการทางานหรืออีนัมเมอเรช่ันให้เสร็จสมบูรณ์เสียก่อนด้วยการแทรกคาส่ัง delay(5000); กอ่ นใช้คาส่ัง Serial.print(); ผลการทางานของโปรแกรมที่ 4-7 แสดงได้ดังรูปท่ี 4-13 โปรแกรมน้ีจะพิมพ์ข้อความ Press 1-5 for control speed of LED : ออกทางพอร์ตอนุกรมแล้วรอให้ผู้ทดลองกดปุ่ม 1 ถึง 5 ทแ่ี ป้นคยี ์บอรด์ โดยกด 1คือให้ LED ติด 0.1 วินาทีและดับ 0.1 วินาทีและถ้ากด 5 จะทาให้ LED ติด 0.5 วินาทีและดับ 0.5 วินาทีถ้าไม่ใช่ปุ่ม 1 ถึง 5 โปรแกรมจะไม่ตอบสนอง เมื่อกดแล้วโปรแกรมจะส่งรหัส ASCII ของปุ่มนี้กลับคืนเพ่ือแจ้งผู้ทดลองแล้วนา คา่ ทไ่ี ดไ้ ปคานวณ ค่าหน่วงเวลาการตดิ ดับของ LED
ที่หน้าต่าง Serial Monitor ของ Arduino เม่ือต้องการส่งข้อความให้พิมพ์ข้อความท่ีต้องการในช่องว่าง ด้านบนเมื่อพิมพ์เสร็จให้คลิกปุ่ม Sendค่ารหัส ASCII ของตัวอักษร 1,2,3,4 และ 5 คือ 49,50,51,52 และ 53 ตามลาดับในการคานวณค่าหน่วงเวลาของฟังก์ช่ัน delay() ทาได้โดยนาค่ารหัส ASCII ของตัวอักษรลบด้วย 48 แลว้ นาคา่ ท่ีไดค้ ณู ดว้ ย 100ซึง่ มีสตู รดงั น้ี delayTime=(incomingByte-48)*100; การตรวจจบั อินพุตจากการกดป่มุ 1 ถึง 5 ของผูใ้ ชง้ านทาไดโ้ ดยใชค้ าส่ัง if โดยกาหนดเงอื่ นไขดังนี้ if(incomingByte >= 49 && incomingByte <=53) เงื่อนไขของคาส่ังนี้จะเปน็ จริงเมือ่ ค่าของข้อมูลที่รับได้มากกว่าหรือเท่ากับ 49 และต้องน้อยกว่าหรือเท่ากั บ 53 จึงจะคานวณค่าหน่วงเวลาใหม่ถ้าเป็นปุ่มอ่ืนเง่ือนไขของคาส่ัง if เป็นเท็จจะกาหนดให้ข้ามส่วนคานวณค่า หน่วงเวลาไป 2.3 ฟงั กช์ ่ันอนิ พุตเอาตพ์ ุตอะนาลอก int analogRead(pin)
อ่านค่าจากขาพอร์ตที่กาหนดให้เป็นอินพุตอะนาลอก บอร์ด Arduino Uno มีวงจรแปลงสัญญาณอะนา ลอกเป็นดิจิตอลความละเอียด 10 บิตทาให้แปลงค่าแรงดันอินพุต 0 ถึง +5V ให้เป็นข้อมูลตัวเลขจานวนเต็ม ระหว่าง 0ถึง 1,023 พารามิเตอร์ pin คอื หมายเลขของขาอินพุตอะนาลอกมีคา่ 0 ถงึ 11 หรือเป็นตัวแปรทีใ่ ช้แทนค่า 0 ถึ ง 11 คา่ ทีส่ ่งกลบั เลขจานวนเต็มจาก 0 ถึง 1023 หมายเหตุ สาหรบั ขาท่เี ป็นอนิ พุตอะนาลอกไมจ่ าเปน็ ต้องประกาศแจ้งวา่ เปน็ อินพุตหรือเอาตพ์ ุต ตวั อย่างการเขียนโปรแกรม int ledPin = 13; // LED connected to digital pin 13 int analogPin = 3; // potentiometer connected to analog pin 3 int val = 0; // variable to store the read value int threshold = 512; // threshold void setup() { pinMode(ledPin, OUTPUT); // sets the digital pin 13 as output } void loop() { val = analogRead(analogPin); // read the input pin if (val >= threshold) { digitalWrite(ledPin, HIGH); // LED on ตัวอ}ยe่างนี้จะสงั่ ให้ขา 13 เป็น HIGH เมอื่ อา่ นค่าจากขา analogPin แล้วมคี ่ามากกวา่ หรือเท่ากบั ค่า เงอ่ื นไขที่กาหlsนeดไว้ (ในตัวอย่างค่าเงื่อนไขหรือ threshold = 255) ทาให้ LED ทีต่ ่ออยู่ติดสว่างแตถ่ ้ามีคา่ น้อยวา่ ขา 13 จะเปน็{ LOW ทาให้ LED ดบั 4.3.1.2 anadloiggitWalrWitreit(ep(lined,Pvina,luLeO)W); // LED off ใชใ้ น}การเขยี นคา่ อะนาลอกไปยังขาพอร์ตโดยใชก้ ารส่ังสัญญาณออกในรปู แบบของสัญญาณ PWM }
พารามิเตอร์ - pin คอื หมายเลขขาพอร์ตของโมดูล POP-MCU - value คอื เป็นคา่ ดิวต้ีไซเกิลมคี ่าระหวา่ ง 0 ถึง 255 เม่อื ค่าเปน็ 0 แรงดันของขาพอร์ตทก่ี าหนดจะเป็น 0V เม่อื มคี ่าเปน็ 255 แรงดันทขี่ าพอรต์ จะเป็น +5V สาหรับค่าระหวา่ ง 0 ถึง 255 จะทาใหข้ าพอรต์ ทก่ี าหนดไวม้ ีค่าแรงดันเปลี่ยนแปลงในยา่ น 0 ถึง 5V หมายเหตุ ขาพอร์ตท่ีใช้สร้างสัญญาณ PWM ด้วยฟังก์ช่ัน analogWrite () ซึ่งจะสามารถใช้ได้เพียง 5 ขาก็คือขา 3, 5, 9, 10 และ11 และจะมีความพิเศษจากขาที่เป็นพอร์ตดิจิตอลปกติคือไม่ต้องกาหนดค่าเพ่ือเลือกเป็น INPUT หรอื OUTPUTค่าความถ่ขี องสัญญาณ PWM มคี า่ ประมาณ 490Hz ผู้ใช้งานสามารถนาสญั ญาณท่ีได้จากคาสัง่ น้ีไปใชใ้ นการปรับความสว่างของ LED หรือต่อขยายกระแสเพ่ือ ต่อปรับความเร็วของมอเตอร์ได้หลังจากเรียกใช้คาสั่งนี้ที่ขาพอร์ตที่กาหนดจะมีสัญญาณ PWMส่งออกมาอย่าง ต่อเน่ืองจนกว่าจะเรียกใชค้ าสั่ง analogWrite (หรือเรยี กคาส่ัง digitalRead หรอื digitalWriteท่ขี าเดียวกนั ) ตวั อยา่ งการเขียนโปรแกรม int ledPin = 11; // LED connected to digital pin 11 int analogPin = 0; // potentiometer connected to analog pin 0 int val = 0; // variable to store the read value void setup() { pinMode(ledPin, OUTPUT); // sets the pin as output } void loop() { คกกับาวรบขทคาดมุ 1ล1ภอใางหยอ้เใินปนva1/}พ/nน็a0บaalตุ2ไอnlป=3อoaร,ตglะa์ดoWานngมaAาWrlคrลiodtา่rgอeiuท(Rtกlei่ีอeneขdvaา่oอPadนงl(iUuไnaบดenn,อs้จavoราlfaorด์กlมogต/วีmPA4ัวงirn)ตจ0d;)้าร;/tuน/แo/i/aปทn2nrลา5eoaนa5งlodสUปgัญtรnRhับญoeeคaาind่าณpไvดuอaท้tะlupนี่ตei่อาnsลกgอับoกขfเาrปoA็mน0ด0ิจ(ตtิตoรองลกคบั วขาาคมวล1าะ8มเ)อสียวดา่ตงัว1ขอ0อยงบ่าLงติ นEจDจี้ าะทน่ีตวน่อ 6 ชอ่ งซ่ึงได้กาหนดขาต่อเป็น A0 ถึง A5 วงจรแปลงสัญญาณอะนาลอกเป็นดิจิตอลมีความละเอียด 10 บิตทาหน้าท่ี
แปลงแรงดันอินพุต 0 ถึง5V เป็นค่าเลขจานวนเต็ม 0 ถึง 1023 ฟังก์ช่ันสาหรับอ่านค่าจากอินพุตอะนาลอกคือ analogRead() โดยค่าในวงเล็บคือหมายเลขของช่องสัญญาณท่ีต้องการอ่านค่า (0 ถึง 11) เม่ือฟังก์ชัน่ ทางานเสร็จ จะคืนคา่ เป็นเลขจานวนเต็ม (int) จาก 0 ถงึ 1,023 ถา้ ต้องการคานวณเปน็ ค่าแรงดนั ท่ีมีหน่วยเป็นโวลต์ (Volt : V) กระทาไดจ้ ากความสัมพนั ธ์ดังน้ี volt = คา่ ท่ีอ่านได้ x 5 /1023 การทดลองอา่ นค่าอนิ พตุ อะนาลอกและส่งค่าออกพอรต์ อนกุ รม ในการทดลองนี้จะตอ้ งตอ่ วงจรเพิม่ เตมิ คือตัวต้านปรบั คา่ ได้ทีต่ อ่ กบั กับไฟเล้ียง +5V และกราวนโ์ ดยมวี งจรดงั รูป จากการทางานของโปรแกรมพบวา่ ตัวโปรแกรมจะสง่ ผลการแปลงสญั ญาณอะนาลอกซึ่งกค็ ือค่าแรงดันไฟ ตรงเปน็ ขอ้ มูลดจิ ิตอลของเลขจานวนเตม็ จาก 0 ถงึ 1023 ถา้ ต้องการให้ส่งข้อมูลเป็นค่าของแรงดันในหน่วยโวลต์ (V) ท่ีมีการแสดงเป็นตวั เลขทศนิยมออกทางพอร์ต อนุกรมจะต้องมีการแก้ ไขโปรแกรมเล็กนอ้ ยดังแสดงโปรแกรมท่ีแก้ไขแลว้ ในโปรแกรมท่ี 4-9ในโปรแกรมท่ี 4-9 นี้ การคานวณเพือ่ แปลงค่าที่อา่ นได้ จากอินพุต A0 ให้เป็นแรงดันหากใชส้ ูตร temp = analogValue*5.0/1023; จะได้ คา่ แรงดันเป็นตัวเลขทศนิยมเสร็จแล้วให้ นาค่าท่ีได้ไปเข้าฟังก์ ชั่ น sprintf() เพ่ือแปลงค่าตัวเลขให้ เป็นตัวอักษรจากการทดลองพบว่า ฟังก์ช่ั น sprintf() ของ Arduino ไม่สามารถใช้ กับตัวแปรเลขทศนิยมได้จึง ตอ้ งดดั แปลงสูตรการแปลงค่าเปน็ แรงดันดังนี้
temp = analogValue*5.0/1023*1000; คาตอบที่ได้เป็นเลขจานวนเต็มจาก 0000 (0V) ถึง 5000 (5 V) แล้วจึงแปลงเป็นข้อความและส่งออก พอร์ตอนกุ รมทีละตัวอกั ษรโดยต้องใสต่ าแหนง่ ของจุดทศนยิ มให้ถูกต้อง เมื่อเปรียบเทียบขนาดไฟล์ท่ีได้หลังการคอมไพล์ของโปรแกรมที่ 4-8 และ 4-9 พบว่าไฟล์มีขนาดใหญ่ข้ึน จาก 2,726 ไบต์เป็น 5,166 ไบตเ์ น่ืองจากมีการเรียกใชฟ้ ังกช์ ่ัน sprintf เพ่ือแปลงตัวเลขให้เป็นข้อความก่อนดังน้ัน ในการใช้งานไมโครคอนโทรลเลอร์จึงนิยมสง่ เปน็ ข้อมลู ดบิ แล้วใหฝ้ ่ังรบั ซงึ่ กค็ ือคอมพิวเตอรน์ าข้อมลู นี้ไปคานวณต่อ ตวั อย่างโปรแกรมภาษา C ของ Arduino สาหรับอ่านค่าอินพุตอะนาลอกแล้วส่งข้อมูลที่ได้จากการแปลง สัญญาณออกไปท่ี พอร์ตอนุกรม ผลการทางานของโปรแกรม แสดงผา่ นหนา้ ตา่ ง Serial Terminal ของ Arduino IDE
การทดลองเอาต์ พุตอะนาลอกของบอร์ด Arduino Uno ใน Arduino มีฟังก์ชั่น analogWrite() ทาให้สร้างสัญญาณอะนาลอกส่งออกทางขาพอร์ตเอาต์พุตได้โดย อาศัยเทคนิคการสร้างสัญญาณ PWM (Pulse Width Modulation) หรือสัญญาณมอดูเลชั่นทางความกว้างพั ลส์ ผู้ใช้งานสามารถปรับค่าดิวตี้ไซเกิลของสัญญาณพัลส์ได้ระหว่าง 0 ถึง 255 เมื่อค่าเป็ น 0 แรงดันของขาพอร์ตท่ี กาหนดไว้จะมีค่าเป็น 0V หากมีค่าเป็น 255 แรงดันท่ีขาพอร์จะเป็น +5V สาหรับค่า 0 ถึง 255 จะทาให้ขาที่ กาหนดไว้ มีค่าแรงดันเปลี่ยนแปลงสลับไปมาระหว่าง 0 และ 5V ถ้ามีค่าสูงช่วงเวลาที่ขาพอร์ตน้ันมีแรง 5V จะ นานขึ้น ถ้าค่าเป็น 51 สัญญาณพัลส์จะมีระดับสัญญาณ +5V เป็นเวลานาน 20% ของคาบเวลาและมีแงดัน0V นาน 80% ของคาบเวลาหรือมีค่าดิวตี้ไซเกิลเท่ากับ 20%น่ันเอง ถ้ามีค่าเป็น 127 สัญญาณพัลส์จะมีระดับสัญญาณ +5V เป็นเวลานานครึ่งหนึ่งของคาบเวลา และ 0V นานครึง่ หนึง่ ของคาบเวลาหรือมคี ่าดิวตไี้ ซเกิล 50% ถา้ มคี ่าเป็น 191 นั่นคือสัญญาณพัลส์จะมีระดับสัญญาณ +5V เป็นเวลานานสามสว่ นส่ีของคาบเวลาและ มีแรงดนั 0V นานหนึ่งสว่ นสี่ของคาบเวลาหรอื มีค่าดิวต้ีไซเกิล 75% รปู แสดงสญั ญาณ PWM ที่ค่าดิวตี้ไซเกลิ ต่างๆ
การคานวณหาคา่ ดวิ ตไ้ี ซเคลิ ของสัญญาณพัลล์ ตัวอยา่ งการต่อวงจรและการเขยี นโปรแกรมเพอื่ ทดสอบการทางานของฟงั กช์ ั่น analogWrite()
ค่าแรงดันของสัญญาณพัลส์จะได้เป็นค่าเฉลี่ยของสัญญาณพัลส์ซึ่งสามารถคานวณได้จากความสัมพันธ์ ทางคณติ ศาสตร์ตอ่ ไปนี้
Outout_voltage = (on_time / off_time) * max_voltage เราสามารถนาสัญญาณ PWM ท่ีได้จากคาสัง่ analogWrite() นีไ้ ปปรับความสว่างของ LED หรือต่อขยาย กระแสเพื่อควบคุมความเร็วของมอเตอร์ไฟตรงได้หลังจากเรียกใช้คาสั่งนี้แล้วขาพอร์ตท่ีกาหนดจะมีสัญญาณ PWM สง่ ออกมาอย่างต่อเน่อื งจนกว่าจะมีการเรียกใช้คาส่งั analogWrite ในรอบใหม่หรือเรียกคาส่ัง digitalRead หรอื digitalWrite ทขี่ าพอร์ตเดยี วกัน ฮาร์ดแวร์Arduino Uno มีขาพอร์ตที่ทาหน้าที่เป็นเอาต์พุตอะนาลอกได้ 5 ขาคือ ขา3, 5, 9, 10 และ 11 การสัง่ ใหข้ าพอรต์ เปน็ เอาตพ์ ุตอะนาลอกจะต้องส่งั ผา่ นฟังกช์ น่ั analogWrite() มรี ปู แบบดงั น้ี analogWrite(pin,value); เมื่อ pin คือ หมายเลขขาพอรต์ ท่ตี อ้ งการ (3, 5, 9, 10 และ 11) value คอื ค่าดิวต้ไี ซเกิลที่ต้องการคา่ จาก 0 ถึง 255 การทดลองน้ีจะสาธิตการใช้ฟังกช์ ั่น analogWrite() โดยกาหนดใหข้ า 11 ทางานเปน็ ขาพอร์ต PWM เพื่อ สร้างสัญญาณ PWM ท่ีมีค่าดิวตี้ไซเกิลจาก 0 ถึง 255 ทาให้LED ท่ีต่ออยู่มีการติดสว่างไล่จากดับไปสว่างท่ีสุด จากน้ันเปลยี่ นค่าดิวต้ีไซเกิลเป็นจาก 255 ลดลงไปถึง 0 ทาให้ LED ท่ีติดสว่างที่สุดค่อยๆ หรี่ลงจนดับจากน้ันการ ทางานจะวนกลบั ไปขับLED ให้ตดิ สวา่ งอกี คร้ัง 2.4 ฟังกช์ ั่นเกีย่ วกบั เวลา (Time) unsigned long millis() คืนค่าเป็นค่าเวลาในหน่วยมิลลิวินาทีนับต้ังแต่บอร์ด Arduino Uno เร่ิมรันโปรแกรมจนถึงเวลาปัจจุบัน ค่าท่ีส่งกลับจากฟังก์ช่ัน ค่าเวลาในหน่วยเป็นมิลลิวินาทีต้งั แตเ่ ริ่มรันโปรแกรมปัจจุบันคื นค่าเป็น unsigned long คา่ ตวั เลขจะเกิดการโอเวอร์โฟลว (ค่าเกินแล้วกลับเป็นศูนย์ ) เมือ่ เวลาผา่ นไปประมาณ 9 ช่ัวโมง ตวั อยา่ งการเขยี นโปรแกรม
long time; void setup() { Serial.begin(9600); } void loop() { Serial.print(\"Time: \"); time = millis(); Serial.println(time); //prints time since program started delay(1000); // wait a second so as not to // send massive amounts of data } delay(ms) เป็นฟังกช์ น่ั ชะลอการทางานหรือหน่วงเวลาของโปรแกรมตามเวลาที่กาหนดในหน่วยมิลลวิ ินาที พารามิเตอร์ ms คือ ระยะเวลาทตี่ ้องการหน่วงเวลาหน่วยเปน็ มลิ ลวิ ินาที (1000 ms เท่ากบั 1 วนิ าที ) ตวั อยา่ งการเขียนโปรแกรม
int ledPin = 13; // LED connected to pin 13 void setup() { pinMode(ledPin, OUTPUT); // sets as output } void loop() { digitalWrite(ledPin, HIGH); // LED on delay(1000); // waits for a second digitalWrite(ledPin, LOW); // LED off delay(1000); // waits for a second } จากตัวอยา่ งน้ีกาหนดให้ pin หมายเลข 13 เปน็ เอาต์พตุ ส่งั ให้เปน็ HIGH (LED ตดิ ) หยุดรอ 1000 มลิ ลิวนิ าที (1 วินาที ) แล้วสั่งเป็น LOW (LED ดับ) แล้วหยุดรอ 1000 มลิ ลิวนิ าทีจากนนั้ วนกลบั ไปทางาน คาส่ังแรกใน void loop() อกี ครงั้ delayMicroseconds(us) เป็นฟงั ก์ชน่ั ชะลอการทางานหรือหน่วงเวลาของโปรแกรมตามเวลาทก่ี าหนดในหน่วยไมโครวินาที พารามิเตอร์ us คอื คา่ หนว่ งเวลาในหน่วยไมโครวินาที (1000 ไมโครวินาที = 1 มิลลวิ นิ าทีและหนงึ่ ล้านไมโครวินาที = 1 วินาที ) ตวั อย่างการเขียนโปรแกรม จากตวั อยา่ งน้ีกาหนดให้ขา 11 ทางานเปน็ เอาต์พตุ เพ่ือสง่ สัญญาณพลั ส์ท่มี คี าบเวลา 100 ไมโครวินาที ตอ่ เนอื่ งตลอดเวลา
int outPin = 11; // digital pin 11 void setup() { pinMode(outPin, OUTPUT); // sets as output } void loop() { digitalWrite(outPin, HIGH); // sets the pin on delayMicroseconds(50); // pauses for 50 microseconds digitalWrite(outPin, LOW); // sets the pin off delayMicroseconds(50); // pauses for 50 microseconds } คาเตอื น ฟังก์ช่ันนี้สามารถทางานอย่างแม่นยาในช่วงต้ังแต่ 3 ไมโครวินาทีข้ึนไปไม่สามารถประกันได้ว่า delayMicroseconds จะทางานได้อยา่ งเที่ยงตรงสาหรับคา่ หนว่ งเวลาที่ต่ากว่านี้ เพ่ือให้หนว่ งเวลาได้อยา่ งแม่นยา ฟังก์ชัน่ นี้จะหยุดการทางานของอินเตอร์รัปต์ทาให้การทางานบางอย่างเช่น การรับขอ้ มูลจากพอร์ตอนุกรมหรือการ เพิ่มค่าที่จะส่งกลับคืนโดยฟังก์ช่ัน milis() จะไม่เกิดข้ึนดังน้ันควรจะใช้ฟังก์ชั่นน้ีสาหรับการหน่วงเวลาสั้นๆ ถ้า ตอ้ งการหนว่ งเวลานานๆ แนะนาใหใ้ ชฟ้ งั กช์ ่ัน delay() แทน 2.5 ฟงั ก์ชั่นเกี่ยวกับอนิ เตอร์รปั ต์จากภายนอก การอนิ เตอร์รัปต์ (interrupt) หรือการขัดจังหวะการทางานของซีพียู นับเป็นคุณสมบัติที่ต้องมีในไมโครคอนโทรลเลอร์สมัยใหม่และ เปน็ คุณสมบัติท่ีมีท่ีบทบาทสาคัญอยา่ งมากใน เช่นขณะท่ีระบบกาลงั ทาการลาเลียงขวดไปตามสายพานเพื่อทาการ
บรรจุน้ายา แล้วเกิดเหตุการณ์ขวดหมดจึงต้องมีการขัดจังหวะกระบวนการบรรจุน้ายาชั่วขณะ จนกว่าจะจัดหา ขวดเข้ามาในระบบเปน็ ทีเ่ รียบร้อยกระบวนการทางานกจ็ ะดาเนินตอ่ ไป จากตัวอย่างดังกล่าว ถ้าเปรียบเทียบกับโปรแกรมควบคุมของไมโครคอนโทรลเลอร์ ระบบลาเลียงขวด เพอื่ บรรจุนา้ ยาเปรียบได้กับโปรแกรมหลัก เหตกุ ารณ์ขวดหมดคือเงอื่ ไขของการเกิดอนิ เตอรร์ ัปต์ที่เป็นจริง ทาให้ เกิดอินเตอรร์ ัปต์ขึ้นการจดั หาขวดมาเพิ่มเติมเปรียบไดก้ บั ซีพียูกระโดดออกจากโปรแกรมหลักไปทางานที่โปรแกรม ย่อยบริการอินเตอร์รัปต์เพื่อจัดหาขวดนั่นคือเสร็จส้ินการบริการอินเตอร์รัปต์ ซีพียูก็จะกระโดดกลับมาทางานท่ี โปรแกรมหลักตอ่ ไประบบสายพานลาเลยี งกจ็ ะทางานต่อไปทางานต่อไปตามปกติ attachInterrupt(interrupt, function, mode) ใช้ระบุวา่ เม่อื ขาอินพตุ ที่รับสญั ญาณอนิ เตอรร์ ัปตจ์ ากภายนอกมีการเปล่ียนแปลงเกิดข้ึนจะกาหนดให้ซพี ยี ู กระโดดไปยังฟงั ก์ช่ันใดโดยบอรด์ Arduino Uno มขี าอินพตุ รับสัญญาณอินเตอร์รปั ต์จากภายนอก 2 ขาคือ INT0 ถึง INT1 ซ่งึ ตรงกบั ขา 2 และ 3 ตามลาดบั หมายเหตุ ฟงั ก์ช่นั ทที่ างานเม่อื การอนิ เตอร์รปั ตจ์ ะไมส่ ามารถเรียกใชฟ้ ังกช์ ัน่ milis() และ delay() ไดเ้ มอ่ื เกดิ การตอบสนองอินเตอรร์ ัปต์แล้วดงั นั้นข้อมลู ทีเ่ ข้ามาทางขา serial data อาจสญู หายได้ พารามเิ ตอร์ - Interrupt คอื หมายเลขของช่องอินพตุ อนิ เตอรร์ ปั ต์ (เปน็ int) - function คือ ฟังกช์ ่ันทจี่ ะกระโดดไปทางานเมื่อเกิดอนิ เตอร์รัปตฟ์ ังก์ชน่ั นีต้ ้องไมร่ ับ ค่าพารามเิ ตอร์และไม่มีการคืนคา่ - mode คอื ประเภทสญั ญาณท่ีใช้กระต้นุ ให้เกดิ การอนิ เตอร์รัปต์ o LOW เกิดอินเตอรร์ ัปต์เมอ่ื ขาสญั ญาณเป็นลอจิก “0” o CHANGE เกิดอินเตอรร์ ัปตเ์ มื่อมีการเปล่ียนแปลงลอจิก o RISING เกดิ อินเตอรร์ ัปต์เมอ่ื มกี ารเปล่ียนลอจิก “0” เป็ น “1” o FALLING เกิดอนิ เตอรร์ ัปต์เม่ือมีการเปล่ียนลอจิก “1” เป็น “0” ตัวอยา่ งการเขียนโปรแกรม
int pin = 13; volatile int state = LOW; void setup() { pinMode(pin, OUTPUT); attachInterrupt(0, blink, CHANGE); } void loop() { digitalWrite(pin, state); } void blink() { state = !state; } ตัวอย่างนเ้ี ลือกอนิ พุตอินเตอร์รปั ต์ช่อง 0 กาหนดใหก้ ระโดดไปทางานทีฟ่ ังก์ชัน่ blink เพอ่ื เปล่ยี นสถานะ ลอจกิ ที่ขา 13 เมื่อเกิดการอนิ เตอร์รปั ต์จากการเปลี่ยนแปลงลอจกิ ที่ขา INT0 detachInterrupt(interrupt) ยกเลกิ การใช้งานฟงั กช์ ่นั การอนิ เตอร์รัปต์จากภายนอก พารามิเตอร์ Interrupt คอื หมายเลขของช่องอินพตุ อนิ เตอร์รปั ต์ท่ตี ้องการยกเลกิ (ค่าเปน็ 0 หรือ 1) 2.6 ฟงั กช์ น่ั ทางคณติ ศาสตร์ min(x, y)
หาคา่ ตวั เลขทนี่ ้อยท่สี ดุ ของตัวเลขสองตั ว พารามิเตอร์ x คอื ตัวเลขตัวแรกเป็นข้อมูลประเภทใดกไ็ ด้ y คือ ตัวเลขตวั ทส่ี องเป็นข้อมูลประเภทใดก็ได้ ค่าทีส่ ง่ กลบั จากฟังกช์ น่ั ค่าทีน่ ้อยท่ีสุดของตวั เลขสองตวั ท่ีให้ ตัวอย่างการเขียนโปรแกรม sensVal = min(sensVal, 100); // assigns sensVal to the smaller of sensVal or 100, // ensuring that it never gets above 100. ตัวอย่างนจ้ี ะไดค้ ่าของ sensVal ทไ่ี ม่เกนิ 100 กลับจากฟงั ก์ชนั่ Max (x, y) หาค่าตัวเลขที่มากท่ีสุดของตวั เลขสองตวั พารามิเตอร์ x คือ ตัวเลขตวั แรกเป็นข้อมลู ประเภทใดกไ็ ด้ y คอื ตวั เลขตวั ท่สี องเปน็ ข้อมูลประเภทใดก็ได้ คา่ ทส่ี ่งกลบั จากฟังกช์ นั่ คา่ ทีม่ ากที่สุดของตวั เลขสองตัวท่ีให้ ตัวอย่างการเขยี นโปรแกรม sensVal = max(senVal, 20); // assigns sensVal to the bigger of sensVal // or 20 (effectively ensuring that it is at least 20) จากตัวอยา่ งนค้ี า่ ของ sensVal จะมีคา่ อยา่ งน้อย 20 abs(x) หาคา่ สมั บูรณ์ (absolute) ของตวั เลขเปน็ การทาให้ค่าของตัวแปรเป็นคา่ จานวนเตม็ บวก พารามิเตอร์
x คือ ตวั เลข ค่าทสี่ ง่ กลบั จากฟังก์ชั่น x เมื่อ x มีค่ามากกว่าหรือเท่ากบั ศนู ย์ (x มีคา่ เปน็ บวกหรอื ศนู ย์ ) x เมื่อ x มีคา่ น้อยกว่าศนู ย์ (x มีคา่ ติดลบ) constrain(x, a, b) ปดั คา่ ตวั เลขทีน่ ้อยกว่าหรือมากกว่าให้อย่ใู นชว่ งทีก่ าหนด พารามิเตอร์ x คอื ตัวเลขทตี่ อ้ งการปัดคา่ ใหอ้ ย่ใู นชว่ งที่กาหนดสามารถเปน็ ขอ้ มลู ชนิดใดก็ได้ a คอื คา่ ตา่ สดุ ของช่วงท่ีกาหนด b คอื คา่ สงู สุดของช่วงทกี่ าหนด คา่ ทสี่ ง่ กลับจากฟังก์ชน่ั x เม่อื x มีคา่ อย่รู ะหว่าง a และ b a เมือ่ x มคี ่าน้อยกวา่ a b เมอื่ x มคี า่ มากกว่า b ตัวอยา่ งการเขยี นโปรแกรม sensVal = constrain(sensVal, 10, 150); // limits range of sensor values to between 10 and 150 จากตัวอยา่ งนี้คา่ ของ sensVal จะอยใู่ นชว่ ง 10 ถงึ 150 2.7 ฟังก์ชน่ั เกยี่ วกับตัวเลขสุม่ randomSeed(seed) ใช้กาหนดตัวแปรสาหรบั สร้างตัวเลขสมุ่ โดยสามารถใช้ตวั แปรได้หลากหลายรปู แบบโดยทัว่ ไปจะใช้ค่า เวลาปัจจบุ ัน (จากฟงั กช์ น่ั milis()) แตส่ ามารถใช้ค่าอย่างอื่นได้ เช่นคา่ ที่ได้เมื่อผูใ้ ช้กดสวิตช์หรือคา่ สญั ญาณ รบกวนท่อี า่ นได้จากขาอินพุตอะนาลอก พารามิเตอร์ seed เปน็ ค่าตัวเลขแบบ long int ตวั อยา่ งการเขยี นโปรแกรม
long randNumber; void setup() { Serial.begin(19200); } void loop() { randomSeed(analogRead(0)); randNumber = random(300); Serial.println(randNumber); } ในตวั อย่างนกี้ าหนดให้เกิดการสมุ่ ตัวเลขข้นึ เมื่ออา่ นค่าจากอินพุตอะนาลอกช่อง 0 (A0) ย่านของตวั เลข ส่มุ คอื 0 ถึง 300 เมื่อทาการสมุ่ ตัวเลขแล้วให้แสดงค่าน้ันที่หนา้ ตา่ ง Serial Monitor long random(max), long random (min,max) ใชส้ รา้ งตัวเลขสมุ่ เสมือน (pseudo-random numbers) เพ่ือนาไปใช้ในโปรแกรมก่อนใชฟ้ งั ก์ชนั้ นีจ้ ะต้อง เรียกใช้ฟังก์ช่ัน randomSeed() ก่อน พารามิเตอร์ min กาหนดคา่ ตัวเลขส่มุ ไมน่ ้อยกว่าค่านี้ (เปน็ ออปช่ันเพิ่มเติม) max กาหนดค่าสูงสดุ ของตัวเลขสุ่ม คา่ ที่ส่งกลบั จากฟังก์ชั่น คนื ค่าเปน็ ตัวเลขสุม่ ในชว่ งทกี่ าหนด (เป็นตัวแปร long int) ตวั อยา่ งการเขียนโปรแกรม
long randNumber; void setup() { Serial.begin(19200); } void loop() { randomSeed(analogRead(2)); // return a random number from 50 - 300 randNumber = random(50,300); Serial.println(randNumber); } ในตวั อยา่ งนก้ี าหนดให้สุม่ ตวั เลขเมื่ออา่ นค่าจากอินพุตอะนาลอกช่อง 2 (A2) ยา่ นของตวั เลขสมุ่ คอื 50 ถึง 300 เม่ือทาการสมุ่ ตัวเลขแล้วให้แสดงค่านน้ั ทีห่ น้าตา่ ง Serial Monitor แหลง่ อา้ งอิง: เรยี นรไู้ มโครคอนโทรลเลอร์กบั Arduino และบอรด์ Unicon บริษัท อนิ โนเวตีฟ เอก็ เพอรเิ มนต์ จากดั
Search
Read the Text Version
- 1 - 39
Pages: