- วัสดุที่ต้องการ:
- ข้อกำหนดเบื้องต้น:
- แผนภูมิวงจรรวม:
- การเขียนโปรแกรมนาฬิกาปลุก:
- จำลองสถานการณ์:
- การทำงานของนาฬิกาปลุกดิจิตอลโดยใช้ PIC16F877A:
การปฏิวัติดิจิทัลเริ่มต้นในปี 2493 เปลี่ยนโครงสร้างทางกลและอิเล็กทรอนิกส์แบบอนาล็อกที่มีอยู่ทั้งหมดให้เป็นคอมพิวเตอร์ดิจิทัล เนื่องจากการเติบโตของอุปกรณ์อิเล็กทรอนิกส์ดิจิทัลเป็นแบบทวีคูณทุกวันนี้แทบจะเป็นไปไม่ได้เลยที่บุคคลจะต่อต้านการใช้อุปกรณ์อิเล็กทรอนิกส์ใด ๆ เริ่มตั้งแต่นาฬิกาปลุกที่ปลุกคุณและเครื่องปิ้งขนมปังที่ให้บริการอาหารเช้าทุกอย่างเป็นผลงานจากอุปกรณ์อิเล็กทรอนิกส์ดิจิทัล ความคิดของทั้งหมดเหล่านี้มันเป็นเรื่องที่น่าตื่นเต้นจริงๆที่จะเขียนโปรแกรมสิ่งที่เราเองที่สามารถดำเนินงานที่เรียบง่ายและมีประโยชน์เช่นนาฬิกาปลุกที่เราจะไปสร้างในโครงการนี้กับPICไมโครคอนโทรลเลอร์ก่อนหน้านี้เราได้สร้างนาฬิกาปลุกด้วยไมโครคอนโทรลเลอร์อื่น ๆ:
- นาฬิกาปลุก Raspberry Pi ใช้โมดูล RTC DS1307
- นาฬิกาดิจิตอลที่ใช้ Arduino พร้อมนาฬิกาปลุก
- นาฬิกาปลุกโดยใช้ไมโครคอนโทรลเลอร์ ATmega32
นาฬิกาปลุกนี้จะมีจอ LCD 16x2 ซึ่งจะแสดงเวลาปัจจุบันและเวลาที่ตั้งไว้ เราจะใช้ปุ่มกดสองสามปุ่มเพื่อตั้งเวลาปลุกเมื่อจำเป็น เวลาปัจจุบันจะถูกติดตามโดยใช้โมดูล DS3231 RTCและเราจะใช้การสื่อสาร IIC เพื่อรับค่าเหล่านี้จากโมดูล RTC เราได้เรียนรู้เกี่ยวกับโมดูล RTC และวิธีการเชื่อมต่อกับ PIC แล้ว ดังนั้นขอแนะนำให้อ่านบทช่วยสอนนั้นเราจะข้ามข้อมูลส่วนใหญ่ที่กล่าวถึงในบทช่วยสอนนั้น
วัสดุที่ต้องการ:
- Bread Board - 2Nos
- PIC16F877A
- แหล่งจ่ายไฟ 5V - โมดูลจ่ายไฟ
- คริสตัล 20 MHz
- ตัวเก็บประจุ 33pf - 2Nos
- โมดูล DS3231 RTC
- โมดูลจอแสดงผล LCD 16 * 2
- 10K พอต
- ตัวต้านทาน 10k และ 1K
- ปุ่มกด - 5Nos
- Buzzer
- การเชื่อมต่อสายไฟ
ข้อกำหนดเบื้องต้น:
โครงการนี้ต้องการให้คุณมีความรู้พื้นฐานบางประการเกี่ยวกับไมโครคอนโทรลเลอร์ PIC และวิธีการตั้งโปรแกรม เราจะใช้ GPIOs จอแสดงผล LCD และโมดูล RTC สำหรับโครงการนี้ ดังนั้นจึงควรเรียนรู้วิธีใช้โมดูลเหล่านี้ล่วงหน้า ลิงก์ต่อไปนี้จะช่วยให้คุณเรียนรู้สิ่งเดียวกัน
- การเขียนโปรแกรมแรกของคุณด้วยไมโครคอนโทรลเลอร์ PIC
- การเชื่อมต่อ LCD กับ PIC
- การสื่อสาร I2C โดยใช้ PIC
- DS3231 RTC เชื่อมต่อกับ PIC
แผนภูมิวงจรรวม:
แผนภาพวงจรสำหรับโครงการนาฬิกาปลุกที่ใช้ PICนี้แสดงไว้ด้านล่างซึ่งสร้างขึ้นโดยใช้ซอฟต์แวร์ proteus นอกจากนี้ยังจะใช้สำหรับการจำลองเพิ่มเติมในโครงการนี้
ปุ่มกดทั้งห้าปุ่มจะทำหน้าที่เป็นอินพุตสำหรับตั้งปลุกตามเวลาที่ต้องการ ดังนั้นปลายด้านหนึ่งของปุ่มกดทั้งหมดจึงเชื่อมต่อกับกราวด์และปลายอีกด้านหนึ่งเชื่อมต่อกับพิน PORTB ตัวต้านทานแบบดึงขึ้นภายในจะใช้กับพินเหล่านี้เพื่อหลีกเลี่ยงไม่ให้พินลอย Buzzer จะทำหน้าที่เป็นเอาท์พุตและจะส่งเสียงบี๊บให้เราเมื่อสัญญาณเตือนดังขึ้นและเชื่อมต่อกับพิน PORT S เวลาปัจจุบันจะถูกติดตามโดยโมดูล DS3231 RTCซึ่ง PIC รับข้อมูลผ่านบัส I2C ดังนั้นพิน SCL และ SDA ของโมดูล RTC จึงเชื่อมต่อกับพิน SCL และ SDA ของคอนโทรลเลอร์ PIC จอแสดงผล LCD ติดอยู่กับ PORTD ของ PIC ซึ่งใช้เพื่อแสดงเวลาปัจจุบันและเวลาที่ตั้งไว้ เรียนรู้เพิ่มเติมเกี่ยวกับการใช้โมดูล DS3231 RTC กับ PIC ที่นี่
วงจรที่สมบูรณ์สามารถสร้างบนเขียงหั่นขนม เนื่องจากมีสายไฟสองสามเส้นในการเชื่อมต่อดังนั้นเพียงแค่อดทนและตรวจสอบให้แน่ใจว่าการเชื่อมต่อถูกต้อง การตั้งค่าฮาร์ดแวร์ของฉันมีลักษณะดังนี้ด้านล่างเมื่อฉันเชื่อมต่อเสร็จแล้ว
ฉันใช้โมดูล breadboard และอะแดปเตอร์ 12V เพื่อจ่ายไฟให้กับโมดูล นี่คือแหล่งจ่ายแรงดัน + 5V ของฉัน ฉันต้องใช้เขียงหั่นขนมสองอันเพื่อให้วงจรสะอาด คุณยังสามารถบัดกรีวงจรทั้งหมดเข้ากับบอร์ด perf ได้หากคุณต้องการสร้างโปรเจ็กต์ที่แข็งแกร่งมากขึ้น
การเขียนโปรแกรมนาฬิกาปลุก:
โปรแกรม PIC ที่สมบูรณ์แบบสำหรับโครงการนาฬิกาปลุกนี้สามารถพบได้ที่ด้านล่างของหน้านี้ โครงการนี้ยังต้องการไลบรารีสามไลบรารีสำหรับการใช้ LCD, I2C และ RTC กับ PIC คุณสามารถดาวน์โหลดโค้ดที่สมบูรณ์พร้อมไฟล์ส่วนหัวได้จากไฟล์ ZIP ที่นี่และสามารถเปิดได้โดยใช้ MPLABX หลังจากแตกไฟล์ เพิ่มเติมด้านล่างฉันแค่อธิบายไฟล์ c หลักเป็นตัวอย่างขนาดเล็ก คุณสามารถย้อนกลับไปที่บทช่วยสอนที่กล่าวถึงข้างต้นได้หากคุณต้องการทราบว่าไฟล์ส่วนหัวทำงานอย่างไร
ก่อนที่จะเข้าสู่โปรแกรมหลักเราต้องกำหนดพินที่เราใช้กับชื่อที่มีความหมายมากขึ้น วิธีนี้จะทำให้ใช้งานได้ง่ายในระหว่างการเขียนโปรแกรม หมุดที่กำหนดไว้ในโปรแกรมของเราแสดงอยู่ด้านล่าง
// กำหนดพิน LCD #define RS RD2 // รีเซ็ตพินของ LCD #define EN RD3 // เปิดใช้งานพินของ LCD #define D4 RD4 // บิตข้อมูล 0 ของ LCD #define D5 RD5 // บิตข้อมูล 1 ของ LCD #define D6 RD6 // บิตข้อมูล 2 ของ LCD #define D7 RD7 // บิตข้อมูล 3 ของ LCD // กำหนดปุ่ม # กำหนดMB RB1 // ปุ่มกลาง# กำหนด LB RB0 // ปุ่มซ้าย # กำหนด RB RB2 // ปุ่มขวา # กำหนด UB RB3 // ปุ่มบน # กำหนด BB RB4 // ปุ่มล่าง // กำหนด Buzz #define BUZZ RD1 // Buzzer เชื่อมต่อกับ RD1
ภายใน หลัก ฟังก์ชั่นที่เราเริ่มต้นด้วยการประกาศอินพุตและเอาต์พุตหมุดในโครงการของเรา PORTB ใช้สำหรับปุ่มกดซึ่งเป็นอุปกรณ์อินพุตดังนั้นเราจึงตั้งพินเป็นอินพุตและ PORTD ใช้สำหรับ LCD และกริ่งดังนั้นเราจึงตั้งพินเป็นเอาต์พุต นอกจากนี้พินไม่ควรปล่อยให้ความหมายลอยตัวพิน I / O ควรเชื่อมต่อกับกราวด์หรือกับแรงดันไฟฟ้า + 5V ในกรณีของเราสำหรับปุ่มกดหมุดจะไม่เชื่อมต่อกับสิ่งใดเลยเมื่อไม่ได้กดปุ่มดังนั้นเราจึงใช้ตัวต้านทานแบบดึงขึ้นภายในซึ่งตั้งค่าพินให้สูงเมื่อไม่ใช้งาน สิ่งนี้ทำได้โดยใช้รีจิสเตอร์ควบคุมดังที่แสดงด้านล่าง
TRISD = 0x00; // สร้างหมุดพอร์ต D เป็นส่วนหน้าสำหรับการเชื่อมต่อ LCD TRISB = 0xFF; // สวิตช์ถูกประกาศเป็นพินอินพุต OPTION_REG = 0b00000000; // เปิดใช้งานตัวต้านทานแบบดึงขึ้นที่พอร์ต B สำหรับสวิตช์ BUZZ = 0; // เปิดเสียงกริ่ง
เนื่องจากเรามีไฟล์ส่วนหัวของ LCD และ I2C ที่เชื่อมโยงกับโปรแกรมหลักเราจึงสามารถเริ่มการเริ่มต้น LCD ได้โดยเรียกใช้ฟังก์ชันง่ายๆ สามารถทำได้เช่นเดียวกันสำหรับการเริ่มต้น I2Cเช่นกัน เรากำลังเริ่มการสื่อสาร I2C ที่ 100kHz เนื่องจากโมดูล RTC ทำงานกับ 100kHz
Lcd_Start (); // เริ่มต้นโมดูล LCD I2C_Initialize (100); // เริ่มต้น I2C Master ด้วยนาฬิกา 100KHz
ฟังก์ชันด้านล่างนี้ใช้เพื่อตั้งเวลาและวันที่บนโมดูล RTCเมื่อตั้งเวลาและวันที่แล้วให้ลบบรรทัดนี้ออก ในแต่ละครั้งที่คุณเริ่มโปรแกรมจะมีการตั้งเวลาและวันที่ซ้ำแล้วซ้ำอีก
// ลบบรรทัดด้านล่างเมื่อตั้งค่าเวลาและวันที่เป็นครั้งแรก Set_Time_Date (); // ตั้งเวลาและวันที่ในโมดูล RTC
เพื่อระบุว่าโปรแกรมกำลังเริ่มต้นขึ้นเราจะแสดงหน้าจอแนะนำขนาดเล็กซึ่งจะแสดงชื่อโครงการและชื่อเว็บไซต์ดังที่แสดงด้านล่าง
// ให้ข้อความแนะนำบน LCD Lcd_Clear (); Lcd_Set_Cursor (1,1); Lcd_Print_String ("นาฬิกาปลุก"); Lcd_Set_Cursor (2,1); Lcd_Print_String ("-Circuit Digest"); __delay_ms (1500);
ถัดไป ใน ลูป while เราต้องอ่านเวลาและวันที่ปัจจุบันจากโมดูล RTCซึ่งสามารถทำได้โดยเรียกใช้ฟังก์ชันด้านล่าง
Update_Current_Date_Time (); // อ่านวันที่และเวลาปัจจุบันจากโมดูล RTC
การเรียกใช้ฟังก์ชันข้างต้นจะอัปเดตตัวแปรวินาทีนาทีและชั่วโมงด้วยค่าปัจจุบัน ในการแสดงผลบนหน้าจอ LCD เราต้องแยกเป็นอักขระแต่ละตัวโดยใช้รหัสด้านล่าง
// แยกเป็นถ่านเพื่อแสดงบนถ่านLCD sec_0 = วินาที% 10; ถ่าน sec_1 = (วินาที / 10); ถ่าน min_0 = นาที% 10; ถ่าน min_1 = นาที / 10; ถ่าน hour_0 = ชั่วโมง% 10; ถ่าน hour_1 = ชั่วโมง / 10;
ต่อไปเราจะปรับปรุงค่ามากกว่าหน้าจอ LCDเวลาปัจจุบันจะแสดงในบรรทัดแรกและเวลาที่ตั้งไว้ซึ่งต้องมีการปลุกจะแสดงบนบรรทัดที่สอง รหัสที่เหมือนกันแสดงอยู่ด้านล่าง
// แสดงเวลาปัจจุบันบนหน้าจอ LCD Lcd_Clear (); Lcd_Set_Cursor (1, 1); Lcd_Print_String ("TIME:"); Lcd_Print_Char (hour_1 + '0'); Lcd_Print_Char (ชั่วโมง _0 + '0'); Lcd_Print_Char (':'); Lcd_Print_Char (min_1 + '0'); Lcd_Print_Char (min_0 + '0'); Lcd_Print_Char (':'); Lcd_Print_Char (sec_1 + '0'); Lcd_Print_Char (sec_0 + '0'); // แสดงวันที่บนหน้าจอ LCD Lcd_Set_Cursor (2, 1); Lcd_Print_String ("สัญญาณเตือน:"); Lcd_Print_Char (alarm_val + '0'); Lcd_Print_Char (alarm_val + '0'); Lcd_Print_Char (':'); Lcd_Print_Char (alarm_val + '0 '); Lcd_Print_Char (alarm_val + '0');
ตอนนี้เราได้แสดงเวลาและตั้งเวลาบน LCD เราต้องตรวจสอบว่าผู้ใช้พยายามตั้งเวลาปลุกหรือไม่ ในการดำเนินการนี้ผู้ใช้ต้องกดปุ่มกลางดังนั้นเราจะตรวจสอบว่ากดปุ่มกลางหรือไม่และสลับตัวแปรเพื่อเข้าสู่โหมดตั้งปลุก ปุ่มเดิมจะถูกกดอีกครั้งเพื่อยืนยันว่าได้ตั้งค่าไว้แล้วและในกรณีนี้เราต้องออกจากโหมดตั้งปลุก ดังนั้นเราจึงใช้ด้านล่างบรรทัดของรหัสที่จะเปลี่ยนสถานะของตัวแปรset_alarm
// ใช้ปุ่มกลางเพื่อตรวจสอบว่าต้องตั้งปลุกหรือไม่ ถ้า (MB == 0 && set_alarm == 0) {// หากกดปุ่มกลางและไม่มีการปลุกใน ขณะที่ (! MB); // ปุ่มรอจนกว่าจะถูกปล่อย set_alarm = 1; // เริ่มตั้งค่าการเตือน } if (MB == 0 && set_alarm == 1) {// หากกดปุ่มกลางและไม่ปิดการเตือน ในขณะที่ (! MB); // ปุ่มรอจนกว่าจะถูกปล่อย set_alarm = 0; // หยุดการตั้งค่าการปลุก }
หากผู้ใช้กดปุ่มตรงกลางแสดงว่าเขากำลังพยายามตั้งเวลาปลุก ในกรณีนี้โปรแกรมจะเข้าสู่โหมดตั้งปลุกโดยใช้รหัสด้านบน ภายในโหมดตั้งปลุกหากผู้ใช้กดปุ่มซ้ายหรือขวาหมายความว่าเราต้องเลื่อนเคอร์เซอร์ไปทางซ้ายหรือขวา ในการทำเช่นนี้เราเพียงแค่เพิ่มการลดค่าของตำแหน่งที่จะต้องวางเคอร์เซอร์
ถ้า (LB == 0) {// หากกดปุ่มซ้าย ในขณะที่ (! LB); // รอจนกว่าจะปล่อยปุ่ม pos--; // จากนั้นเลื่อนเคอร์เซอร์ไปทางซ้าย } if (RB == 0) {// ถ้ากดปุ่มขวา ในขณะที่ (! RB); // ปุ่มรอจนกว่าจะถูกปล่อย pos ++; // เลื่อนเคอร์เซอร์ไปทางขวา }
ในขณะที่ใช้ปุ่มกดกับไมโครคอนโทรลเลอร์หรือไมโครโปรเซสเซอร์มีปัญหาทั่วไปอย่างหนึ่งที่ต้องแก้ไข ปัญหานี้จะเรียกว่าเป็นสวิทช์ใหญ่นั่นคือเมื่อกดปุ่มอาจทำให้เกิดพัลส์ที่มีเสียงดังไปยัง MCU / MPU ซึ่งอาจปลอม MCU สำหรับหลายรายการ ปัญหานี้สามารถแก้ไขได้โดยการเพิ่มตัวเก็บประจุข้ามสวิตช์หรือโดยใช้ฟังก์ชันหน่วงเวลาทันทีที่ตรวจพบการกดปุ่ม วิธีการแก้ปัญหาประเภทนี้เรียกว่าการตีกลับ ที่นี่เราได้ใช้ while loop เพื่อให้โปรแกรมอยู่กับที่จนกระทั่งปล่อยปุ่ม นี่ไม่ใช่วิธีแก้ปัญหาการตีกลับที่ดีที่สุด แต่สำหรับเราแล้วมันก็ใช้ได้ดี
ในขณะที่ (! RB);
เช่นเดียวกับปุ่มซ้ายและขวาเรายังมีปุ่มบนและปุ่มล่างซึ่งสามารถใช้เพื่อเพิ่มหรือลดค่าเวลาปลุกได้ รหัสในการทำเช่นเดียวกันแสดงอยู่ด้านล่าง สังเกตว่าอักขระแต่ละตัวของเวลาปลุกที่ตั้งไว้จะถูกกำหนดโดยค่าดัชนีของอาร์เรย์ นี่คือเราสามารถเข้าถึงอักขระที่จำเป็นซึ่งต้องเปลี่ยนค่าได้อย่างง่ายดาย
ถ้า (UB == 0) {// ถ้าปุ่มบนถูกกด ในขณะที่ (! UB); // รอจนกว่าจะปล่อยปุ่ม alarm_val ++; // เพิ่มค่าถ่านนั้น ๆ } if (BB == 0) {// ถ้ากดปุ่มล่าง ในขณะที่ (! UB); // รอจนกว่าจะปล่อยปุ่ม alarm_val--; // ลดค่าถ่านนั้น ๆ }
เมื่อเวลาปลุกในการตั้งค่าผู้ใช้จะกดปุ่มตรงกลางอีกครั้งจากนั้นเราสามารถเริ่มเปรียบเทียบเวลาปัจจุบันกับเวลาที่ตั้งไว้ การเปรียบเทียบโดยตรวจสอบว่าทุกอักขระของเวลาปัจจุบันเท่ากับอักขระของเวลาที่ตั้งไว้หรือไม่ หากค่าเท่ากันเราจะทริกเกอร์การเตือนโดยการตั้งค่าตัวแปร trigger_alarm อื่น ๆ ที่เราเปรียบเทียบจนกว่ามันจะเท่ากัน
// ตั้งปลุก IF ตรวจสอบว่าค่าที่ตั้งไว้เท่ากับค่าปัจจุบันหรือไม่ถ้า (set_alarm == 0 && alarm_val == hour_1 && alarm_val == hour_0 && alarm_val == min_1 && alarm_val == min_0) trigger_alarm = 1; // เปิดทริกเกอร์หากค่าตรงกัน
หากตั้งนาฬิกาปลุกไว้เราจะต้องส่งเสียงบี๊บเพื่อเตือนผู้ใช้ให้ส่งเสียงเตือน ซึ่งสามารถทำได้โดยเพียงแค่สลับ Buzzer ในช่วงเวลาปกติดังที่แสดงด้านล่าง
if (trigger_alarm) {// หากมีการปลุก // บี๊บเสียง BUZZ = 1; __delay_ms (500); BUZZ = 0; __delay_ms (500); }
จำลองสถานการณ์:
โปรแกรมนี้ยังสามารถจำลองโดยใช้ซอฟต์แวร์โปรตีอุส เพียงสร้างวงจรที่แสดงด้านบนขึ้นมาใหม่และโหลดไฟล์ฐานสิบหกลงใน PIC รหัสฐานสิบหกสำหรับโครงการนี้สามารถพบได้ที่ไฟล์ ZIP ที่เชื่อมโยงที่นี่ ภาพหน้าจอที่ถ่ายระหว่างการจำลองจะแสดงด้านล่าง
การจำลองจะมีประโยชน์มากเมื่อคุณพยายามเพิ่มคุณสมบัติใหม่ให้กับโปรเจ็กต์ คุณยังสามารถใช้โมดูลดีบักเกอร์ I2C เพื่อตรวจสอบว่าข้อมูลใดเข้าและออกผ่านบัส I2C คุณสามารถลองกดปุ่มและตั้งเวลาปลุกได้ เมื่อเวลาที่ตั้งไว้เท่ากับเวลาปัจจุบันเสียงกริ่งจะดังขึ้น
การทำงานของนาฬิกาปลุกดิจิตอลโดยใช้ PIC16F877A:
สร้างวงจรบน breadboard รับโค้ดจากลิงค์ดาวน์โหลดและคอมไพล์โดยใช้คอมไพเลอร์ MplabX และ XC8 หากคุณดาวน์โหลดรหัสจากไฟล์ ZIP ที่ให้ไว้ที่นี่คุณจะไม่มีปัญหาในการคอมไพล์เนื่องจากแนบไฟล์ส่วนหัวเรียบร้อยแล้ว
หลังจากรวบรวมอัปโหลดโปรแกรมไปยังฮาร์ดแวร์ของคุณโดยใช้โปรแกรมเมอร์ PicKit3 การเชื่อมต่อเพื่อเชื่อมต่อโปรแกรมเมอร์ pickit กับ PIC IC ยังแสดงอยู่ในแผนภาพวงจร หลังจากอัปโหลดโปรแกรมแล้วคุณจะเห็นหน้าจอแนะนำจากนั้นเวลาที่แสดงคุณสามารถใช้ปุ่มกดเพื่อตั้งเวลาปลุกได้ การตั้งค่าฮาร์ดแวร์ของฉันเมื่อขับเคลื่อนมีลักษณะดังนี้ด้านล่าง
เมื่อเวลาปลุกตรงกับเวลาปัจจุบันกริ่งจะเริ่มส่งเสียงบี๊บเพื่อปลุกผู้ใช้ สามารถดูการทำงานทั้งหมดได้ที่วิดีโอด้านล่าง โครงการมีตัวเลือกมากมายให้สร้าง โมดูล RTC สามารถติดตามเวลาและวันที่ใดก็ได้ดังนั้นคุณสามารถทำงานตามกำหนดเวลาได้ตลอดเวลา / วันที่ที่ต้องการ คุณยังสามารถเชื่อมต่ออุปกรณ์ AC เช่นพัดลมหรือไฟและตั้งเวลาให้เปิดหรือปิดเมื่อจำเป็น ยังมีอะไรอีกมากมายที่คุณสามารถต่อยอดจากโปรเจ็กต์นี้ได้โปรดแจ้งให้เราทราบว่าคุณมีแนวคิดใดในการอัปเกรดโครงการนี้และเรายินดีที่จะรับฟังความคิดเห็นจากคุณ
หวังว่าคุณจะเข้าใจโครงการและเรียนรู้สิ่งที่เป็นประโยชน์จากกระบวนการนี้ หากคุณมีข้อสงสัยในโครงการนี้ให้ใช้ส่วนความคิดเห็นเพื่อโพสต์หรือใช้ฟอรัมเพื่อขอความช่วยเหลือด้านเทคนิค
สามารถดูรหัส PIC ที่สมบูรณ์พร้อมไฟล์ส่วนหัวได้ที่นี่