เรียนรู้การใช้งาน Watch Dog Timer (WDT) โมดูลภายใน Arduino - Griffinics

Latest

เว็บบล็อกนี้จัดทำขึ้นเพื่อเก็บสะสมองค์ความรู้และประสบการณ์ด้านต่างๆ ที่ผู้เขียนได้เรียนรู้ระหว่างเส้นทางชีวิตการงาน ไว้เป็นวิทยาทานแด่ศิษย์อาจารย์ Google ทุกทาน

วันศุกร์ที่ 3 มีนาคม พ.ศ. 2566

เรียนรู้การใช้งาน Watch Dog Timer (WDT) โมดูลภายใน Arduino



ในบางครั้งการทำงานของโปรแกรมที่เราเขียนในไมโครคอนโทรลเลอร์อาจทำงานผิดพลาดหรือเกิดข้อผิดพลาดจนทำให้มีอาการโปรแกรมแฮงค์ เครื่องค้าง ไม่ทำงานต่อเนื่องตามที่เราต้องการ ซึ่งเป็นอาการที่ไม่ได้เกิดขึ้นบ่อยๆ แต่เกิดขึ้นได้ สำหรับโปรแกรมที่ต้องทำงานตลอดเวลาที่ต้องการความเสถียรสูงโปรแกรมจะหยุดทำงานไม่ได้ ซึ่งจำเป็นอย่างยิ่งที่ต้องมีระบบตรวจสอบการทำงาน ซึ่งระบบนี้ในไมโครคอนโทรลเลอร์จะเรียกว่า Watch Dog Timer (WDT) หรือสุนัขเฝ้าดูนั่นเอง ในวงจรควบคุมทางอิเล็กทรอนิกส์และคอมพิวเตอร์ต่างๆ จะต้องมีวงจรนี้ และสำหรับบอร์ด Arduino Uno ก็มีมาเช่นกัน

หลักการทำงานของ Watch Dog Timer

WDT จะทำงานโดยอาศัยการตรวจสอบสัญญานนาฬิกาของวงจรซึ่งเปรียบได้กับชีพจรของคนเรา โดยจะมีความถี่ระยะเวลาในการตรวจสอบ เช่น ทุกๆ กี่มิลลิวินาที, กี่วินาที ก็แล้วแต่การตั้งค่า ซึ่งในระยะเวลาที่กำหนดวงจรหรือโปรแกรมจะต้องส่งสัญญานให้กับ WDT หากครบกำหนดเวลาแล้วถ้ายังไม่มีการสัญญาน WDT จะถือว่าการทำงานของโปรแกรมล้มเหลว และจะต้องทำการขัดจังหวะการทำงาน เช่น สั่งรีเซตการทำงานทั้งหมด เป็นต้น

ไลบลารี่ที่ใช้

#include <avr/wdt.h>

  • ฟังก์ชั่นที่ใช้งาน
wdt_enable(WDTO_xx);      ใช้สำหรับเปิดการใช้งาน Watch Dog Timer

    WDTO_xS คือ ค่าเวลาที่ต้องการให้ WDT ตรวจสอบสัญญาณการทำงานโดย x เป็นเวลาหน่วย มิลลิวินาที (mS) หรือ 1/1000 วินาที, วินาที (S) มีค่าดังนี้

WDTO_15MS ตรวจสอบสัญญาณการทำงานทุก 15 มิลลิวินาที
WDTO_30MS ตรวจสอบสัญญาณการทำงานทุก 30 มิลลิวินาที
WDTO_60MS ตรวจสอบสัญญาณการทำงานทุก 60 มิลลิวินาที
WDTO_120MS ตรวจสอบสัญญาณการทำงานทุก 120 มิลลิวินาที
WDTO_250MS ตรวจสอบสัญญาณการทำงานทุก 250 มิลลิวินาที
WDTO_500MS ตรวจสอบสัญญาณการทำงานทุก 500 มิลลิวินาที
WDTO_1S ตรวจสอบสัญญาณการทำงานทุก 1 วินาที
WDTO_2S ตรวจสอบสัญญาณการทำงานทุก 2 วินาที
WDTO_4S ตรวจสอบสัญญาณการทำงานทุก 4 วินาที
WDTO_8S ตรวจสอบสัญญาณการทำงานทุก 8 วินาที

*ภายในเวลาที่กำหนด หาก WDT ยังไม่ถูกรีเซต แสดงว่าการทำงานของโปรแกรมอาจผิดพลาด เช่น โปรแกรมแฮงค์ ดังนั้น WDT จะสั่งให้ Arduino Uno รีสตาร์ตการทำงาน เพื่อให้โปรแกรมทำงานต่อไปได้

wdt_reset();      ใช้สำหรับสั่งให้ Watch Dog Timer เริ่มนับเวลาใหม่ ซึ่งคำสั่งนี้จะทำให้ WDT รู้ว่าการทำงานยังปกติ


wdt_disable();     ใช้ปิดการใช้งาน Watch Dog Timer


เพื่อให้เข้าใจหลักการทำงานของ WDT มากขึ้น ลองมาเขียนโค้ดเพื่อทดสอบการทำงานของ WDT ง่ายๆกันโดยการกำหนดการหน่วงเวลาและสังเกตการทำงานของโปรแกรมจากการปริ้นต์ข้อความผ่าน Serial Monitor ดังนี้

ตัวอย่างการใช้ WDT กับบอร์ด Arduino UNO

 โปรแกรมนี้ทดสอบการทำงานของ WDT โดยการหน่วงเวลา 1 วินาที   เพื่อทดสอบการทำงานของ WDT ซึ่งค่าการตรวจสอบของ Hardware WDT ตรวจสอบ ทุกๆ 2 วินาที ในการทดสอบนี้จะทดสอบในสภาวะการทำงานปกติ


#include <avr/wdt.h>
void setup()
{
Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
wdt_enable(WDTO_2S); // สั่งให้ WDT เริ่มจับเวลา 2 วินาที ถ้าเกินให้ Reset โปรแกรมใหม่
Serial.println("Reset");
}
void loop()
{
//wdt_disable();
Serial.println("Arduino All Working...");
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000);
wdt_reset(); //สั่งให้ WDT เริ่มจับเวลาใหม่
}




เมื่อหน่วงเวลา 1 วินาที แล้วใช้คำสั่ง wdt_reset() ให้ Watch Dog Timer เริ่มนับเวลาใหม่ ซึ่งจะไม่เกิน 2 วินาที เสมือนกับโปรแกรมการทำงานเป็นปกติ โปรแกรมก็จะปริ้นต์ Arduino All Working... ต่อเนื่องดังรูป


ทดสอบการทำงานของ WDT เมื่อโปรแกมทำงานผิดปกติ เช่น โปรแกรมแฮค์ หรือหยุดการทำงานนานเกิน 2 วินาที สมมุติสถานะการณ์โดยหน่วงเวลาเพิ่มเป็น 3 วินาที ซึ่งเกินค่าการตรวจสอบของ Hardware WDT 

#include <avr/wdt.h>
void setup()
{
Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
wdt_enable(WDTO_2S); // สั่งให้ WDT เริ่มจับเวลา 2 วินาที ถ้าเกินให้ Reset โปรแกรมใหม่
Serial.println("Reset");
}
void loop()
{
//wdt_disable();
Serial.println("Arduino All Working...");
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(3000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(3000);
wdt_reset(); //สั่งให้ WDT เริ่มจับเวลาใหม่
}

เมื่อ WDT นับเวลาตรวจสอบการทำงานจนเกิน 2 วินาทีแล้วคำสั่ง wdt_reset(); ยังไม่ทำงาน ทำให้ WDT ทำการรีเซตการทำงานทั้งหมดของบอร์ด สังเกตได้จากการปริ้นต์ Reset เมื่อหน่วงเวลาเกิน 2 วินาที


บทสรุป: หากต้องการให้โปรแกรมทำงานได้อย่างต่อเนื่องมีเสถียรภาพ ทำงานได้อย่างสม่ำเสมอ ไม่ต้องห่วงเรื่องการหยุดทำงานของโปรแกรม การนำ WDT ภายใน Arduino มาใช้งานจึงมีความจำเป็นอย่างยิ่ง

ไม่มีความคิดเห็น:

แสดงความคิดเห็น