Heart Beat คืออะไรวะ?
Heart Beat ก็คือ 'ชีพจร' ที่โปรแกรมเราสร้างขึ้นมาให้เต้นตามความถี่ที่เราตั้งไว้ มันช่วยบอกเราว่าโค้ดหรือแอปพลิเคชันหลักของเรายังทำงานปกติดีอยู่หรือเปล่า โดยปกติแล้ว (แต่ไม่เสมอไปนะ) เราจะแสดง Heart Beat ผ่านการกะพริบของไฟอินดิเคเตอร์ เช่น LED นั่นแหละ ตราบใดที่ไฟยังกะพริบอยู่ ('ยังเต้นอยู่') เราก็รู้ว่าโค้ดยังรันอยู่ แต่ถ้ามันหยุดนิ่งล่ะก็... ถึงเวลาต้องลุย debug แล้วล่ะน้อง
การเพิ่ม Heart Beat indicator เข้าไปในสเก็ตช์ของเราเป็นวิธีที่ง่ายโคตรและใช้ทรัพยากรน้อยมากๆ ในการทำให้เห็นภาพว่าโค้ดเรายังทำงานอยู่ โดยเฉพาะแอปพลิเคชันที่ปกติแล้วมันเงียบเชียบ ไม่มีอะไรให้ดูเลย อย่างเช่น สเก็ตช์ที่คอยอ่านค่าเซ็นเซอร์ แล้วจะส่งสัญญาณเตือนก็ต่อเมื่อค่าถึงขีดจำกัดที่ตั้งไว้ เป็นต้น ในสถานการณ์แบบนี้ การมี Heart Beat มันช่วยให้เรามั่นใจได้ว่าโค้ดไม่ได้หยุดทำงานไปซะก่อน
Heart Beat เนี่ย ต้องมีโค้ดกับชิ้นส่วนอะไรบ้าง?
การทำให้ Heart Beat มันมองเห็นได้เนี่ย ประกอบด้วย 2 ส่วนหลัก:
1. ชิ้นส่วนฮาร์ดแวร์ ที่จะแสดงผลให้เห็นว่า Heart Beat ยังเต้นอยู่ และ
2. ซอฟต์แวร์หรือโค้ด ที่จะมาควบคุมฮาร์ดแวร์ตัวนั้น
แต่เพื่อให้ชีวิตง่ายแบบสุดๆ Heart Beat ที่เราจะพูดถึงในบทความนี้ ไม่ต้องใช้ ชิ้นส่วนฮาร์ดแวร์อื่นใดเพิ่มเติมเลยนอกจากบอร์ดไมโครคอนโทรลเลอร์ที่เข้ากับ Arduino ได้ เพราะเราจะใช้ LED ในตัวที่มาพร้อมกับบอร์ดพวกนี้อยู่แล้ว บอร์ดส่วนใหญ่จะมี LED ในตัว (ใช้ชื่อว่า 'LED_BUILTIN') ติดอยู่ที่ดิจิตอลพิน 13 ซึ่งเราสามารถสั่งงานได้โดยตรง เพราะฉะนั้น แค่ใช้ฟีเจอร์นี้ เราก็ไม่ต้องหาซื้อหรือต่อสายอะไรเพิ่มอีกแล้ว สบายปากเลย งานเราก็จะเหลือแค่โฟกัสที่โค้ดของ Heart Beat เท่านั้น
ซอฟต์แวร์/โค้ดของ Heart Beat
โค้ด Heart Beat สามารถแบ่งออกได้เป็น 4 ส่วน:
1. การประกาศหรือกำหนดค่าตัวแปรต่างๆ ที่จำเป็นต้องใช้,
2. การประกาศฟังก์ชัน heart_beat(),
3. การตั้งค่าเริ่มต้นของ Heart Beat, และ
4. การเรียกใช้ Heart Beat ในตำแหน่งที่ต้องการในโค้ดของเรา
โค้ด Heart Beat ถูกออกแบบมาเป็นฟังก์ชันแบบ non-blocking (ฟังก์ชัน 'heart_beat()') และเราสามารถเอาไปใส่ไว้ที่ไหนในโค้ดก็ได้ แม้แต่หลายๆ ที่พร้อมกันก็ยังได้ แต่ขั้นต่ำสุดนะ ถ้าเราออกแบบลูปหลักให้รันซ้ำๆ การเรียกใช้ heart_beat() ควรจะปรากฏอยู่ในส่วนนี้ด้วย เช่น วางไว้ตอนเริ่มต้นของ loop() เลยก็ได้
มาแยกย่อยดูแต่ละส่วนของโค้ด Heart Beat กันดีกว่า
1. การประกาศ และ การกำหนดค่า
#define heart_beat_pin LED_BUILTIN // digital pin for heart beat LED
long unsigned heart_beat_freq = 1000; // time(milliseconds) of heart beat frequency
long unsigned heart_beat_on_off_time; // the time the LED is on and off - 1/2 frequency
long unsigned last_heart_beat_time; // time in milliseconds of last heart beat status change
bool heart_beat_status = HIGH; // current status of heart beat, start high
เราสามารถปรับแต่งโค้ด Heart Beat ให้เหมาะกับความต้องการได้ โดยการแก้ไขค่าที่ประกาศไว้ด้านบนนี่แหละ ตามนี้:
ใช้ LED ในตัวหรือ LED ภายนอก - ถ้าเราไม่อยากใช้ LED ในตัวของบอร์ด ให้ไปเปลี่ยนค่าของ 'heart_beat_pin' เป็นเลขดิจิตอลพินที่เราต่อ LED ภายนอกไว้แทน แต่ถ้าใช้แบบ default โค้ดก็จะใช้ LED ในตัวที่พิน 13 (ซึ่งรู้จักในชื่อ LED_BUILTIN) อยู่แล้ว ทำให้เราไม่ต้องเสียเวลาต่อสายหรือหาอะไรมาเพิ่มเลย สบายๆ
ปรับความถี่การเต้นของ Heart Beat - เราสามารถตั้งความถี่ที่ Heart Beat จะเต้นได้ โดยการกำหนดค่าตัวแปร 'heart_beat_freq' เป็นจำนวนมิลลิวินาทีที่ต้องการ จำไว้ว่า เวลาที่ LED จะติดและดับนั้น จะเป็นครึ่งหนึ่งของความถี่ที่เราตั้งไว้ ตัวอย่างเช่น ถ้าเราตั้งความถี่ไว้ที่ 1 Hz หรือ 1000 มิลลิวินาที LED ของ Heart Beat ก็จะติดอยู่ 500 มิลลิวินาที และดับ 500 มิลลิวินาที หรือก็คือครึ่งวินาทีต่อครึ่งวินาทีนั่นเอง
ตัวแปรอื่นๆ ทั้งหมดถูกใช้ภายในโค้ดการเต้นของหัวใจ (heart beat) โดยตรง ไม่สามารถกำหนดค่าเองได้
2. ฟังก์ชัน heart_beat()
เพื่อให้เรื่องง่ายเข้าไว้ โค้ดหัวใจเต้นถูกออกแบบมาเป็นฟังก์ชันแบบไม่บล็อกกิ้ง (non-blocking) เรียบง่าย ไม่มีพิธีรีตอง ชื่อว่า 'heart_beat' มันไม่มีพารามิเตอร์ และเป็นประเภท void
ฟังก์ชันหน้าตาแบบนี้:
//
// Function handles the heart beat cycle.
// May be called from anywhere, but at least every main loop cycle.
//
void heart_beat() {
if (millis() - last_heart_beat_time >= heart_beat_on_off_time) {
// time to swap status of the heart beat LED and update it
last_heart_beat_time = millis();
heart_beat_status = !heart_beat_status; // invert current heart beat status value
digitalWrite(heart_beat_pin, heart_beat_status); // update LED with new status
}
}
แค่เอาไปแปะในโค้ดของน้องตรงไหนก็ได้ที่เหมาะสม และต้องมั่นใจว่าเรียกใช้มันอย่างน้อยในส่วน main loop นะจ๊ะ
3. การตั้งค่า Heart Beat
โค้ดหัวใจเต้นจะถูกตั้งค่าเริ่มต้นภายในฟังก์ชัน setup() แบบนี้:
// setup heart beat
pinMode(heart_beat_pin, OUTPUT);
heart_beat_on_off_time = heart_beat_freq / 2; // LED is on and off at 1/2 frequency time
// end of heart beat setup
ตรงนี้ไม่มีอะไรให้ผู้ใช้ปลายทางอย่างน้องต้องทำหรือแก้ไข แค่ต้องแน่ใจว่าโค้ดนี้อยู่ในฟังก์ชัน setup() เท่านั้นเอง วางใจรุ่นพี่ได้เลย
4. การเรียกใช้ Heart Beat
เพื่อให้หัวใจเต้นทำงานได้ จำเป็นและสำคัญมากที่ฟังก์ชัน 'heart_beat()' จะต้องถูกเรียกเป็นประจำ มันสามารถแทรกไว้ที่ไหนก็ได้ในโค้ดแอปพลิเคชันของน้อง แต่ปกติแล้วแนะนำให้เรียกมันในส่วน main loop ของโค้ดจะดีที่สุด เพื่อให้มันวนทำงานเป็นประจำ ถ้าโค้ด main loop ของน้องไม่วนลูปอัตโนมัติล่ะก็ อาจต้องไปเรียกฟังก์ชัน heart_beat() ที่จุดอื่นๆ ในโค้ดที่ถูกเข้าถึงเป็นประจำแทน ฟังก์ชันนี้สามารถเรียกซ้ำกี่ครั้งก็ได้ตามต้องการ โดยไม่ส่งผลกระทบต่อการทำงานปกติของหัวใจเต้น
ตัวอย่างใน main loop ก็ประมาณนี้:
void loop() {
heart_beat();
// add your other code here...
}
รายละเอียดทางเทคนิคเพิ่มเติม
การออกแบบเฟิร์มแวร์แบบไม่บล็อกกิ้ง (Non-Blocking)
"Heartbeat" ในระบบเอมเบดเด็ดเป็นตัวบ่งชี้สถานะและดีบั๊กที่สำคัญมาก
- เทคนิค Millis(): โปรเจคนี้แสดงให้เห็นวิธีหลีกเลี่ยงการใช้ฟังก์ชัน
delay()โดยการใช้millis()ทำให้ Arduino สามารถกะพริบ LED หรือส่งข้อความ Serial ในช่วงเวลาที่กำหนด (เช่น ทุก 1000ms) โดยไม่ต้องหยุดการทำงานของลอจิกหลักของแอปพลิเคชัน - การตรวจสอบสถานะ: ถ้า LED Heartbeat หยุดกะพริบ มันจะให้สัญญาณภาพทันทีว่าไมโครคอนโทรลเลอร์อาจค้างหรือติดอยู่ในลูปอนันต์แล้ว
ประโยชน์ในการนำไปใช้
- การวินิจฉัยตัวเอง: โค้ดนี้สามารถขยายได้เพื่อเปลี่ยนความถี่การเต้นของหัวใจตามสถานะของระบบ (เช่น กะพริบเร็วเมื่อมี Error, กะพริบช้าเมื่อ Normal)
- วอตช์ด็อกไทเมอร์: ลอจิกนี้มักเป็นก้าวแรกสู่การใช้วอตช์ด็อกไทเมอร์ (WDT) แบบฮาร์ดแวร์ ซึ่งสามารถรีเซ็ต Arduino อัตโนมัติได้หากสัญญาณหัวใจเต้นหายไปนานเกินไป
แค่นั้นแหละ! เก็บเทคนิคนี้ไว้ใกล้ตัวและใส่มันลงในสเก็ตช์ของน้องเป็นฟีเจอร์มาตรฐานไปเลย สู้งานนะน้อง!
อ่านเพิ่มเติม
น้องอาจจะพบว่าผลงานอื่นๆ จากผู้เขียนคนเดียวกันนี้น่าสนใจและมีประโยชน์:
- A Music & Lights Workbench ออกแบบมาเพื่อแนะนำผู้ที่ใหม่กับการเขียนโปรแกรมคอมพิวเตอร์ โดยใช้คำสั่งง่ายๆ ที่ให้เอฟเฟกต์เจ๋งๆ แนวทางการสอนเป็นแบบพี่สอนน้อง