Compare commits
8 Commits
95f5cd414e
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
9b3e813327
|
|||
|
3b1d18b001
|
|||
| e6ff2cf07a | |||
| 2baaafb9c9 | |||
|
19fb847b7d
|
|||
|
f72f0be591
|
|||
|
1c627501dd
|
|||
|
f37340d485
|
@@ -5,16 +5,13 @@
|
||||
columns: 2,
|
||||
column-gutter: 2em,
|
||||
row-gutter: 1em,
|
||||
stroke: (none, (bottom: (dash: "dotted"))),
|
||||
[หัวข้อโครงงาน], [เครื่องยืนยันตัวตนด้วย NFC],
|
||||
[นักศึกษา],
|
||||
grid.cell(
|
||||
stroke: none,
|
||||
grid(
|
||||
columns: 2,
|
||||
column-gutter: 1em,
|
||||
row-gutter: 1em,
|
||||
stroke: ((bottom: (dash: "dotted")), none),
|
||||
[นางสาว ประภากร ศรีวรสาร], [รหัสประจำตัว #underline[67219090006]],
|
||||
[นางสาว พีรดา แสงแป้], [รหัสประจำตัว #underline[67219090007]],
|
||||
[นาย ศตคุณ อุตมะ], [รหัสประจำตัว #underline[67219090014]],
|
||||
@@ -31,7 +28,33 @@
|
||||
|
||||
= บทคัดย่อ
|
||||
|
||||
#i โครงงานนี้
|
||||
#i โครงงานนี้มีวัตถุประสงค์เพื่อศึกษาและประยุกต์ใช้เทคโนโลยี NFC ในการยืนยันตัวตน
|
||||
ออกแบบและสร้างเครื่องมือที่สามารถตรวจสอบสิทธิ์การเข้าใช้งานได้อย่างมีประสิทธิภาพ
|
||||
รวมถึงป้องกันการบุกรุกจากบุคคลที่ไม่ได้รับอนุญาต และเพิ่มความสะดวกในการยืนยันตัวตนผ่านโทรศัพท์มือถือ
|
||||
โดยมุ่งเน้นให้ระบบมีการทำงานที่ง่าย รวดเร็ว และมีความน่าเชื่อถือ เหมาะสมต่อการนำไปใช้งานจริง
|
||||
|
||||
#i การดำเนินงานเริ่มจากการศึกษาหลักการทำงานของเซนเซอร์ NFC
|
||||
และอุปกรณ์ไมโครคอนโทรลเลอร์ที่เกี่ยวข้อง
|
||||
จากนั้นทำการออกแบบวงจรและโครงสร้างของอุปกรณ์ให้เหมาะสม
|
||||
ผู้จัดทำได้พัฒนาระบบให้สามารถอ่านข้อมูลจากโทรศัพท์มือถือหรือการ์ด NFC ที่ได้ลงทะเบียนไว้
|
||||
เมื่อมีการนำอุปกรณ์มาสแกนระบบจะทำการตรวจสอบข้อมูลกับฐานข้อมูล
|
||||
หากข้อมูลถูกต้องจะอนุญาตให้เข้าถึงได้ทันที แต่หากไม่ถูกต้องระบบจะปฏิเสธการเข้าถึง
|
||||
เพื่อป้องกันการใช้งานจากบุคคลที่ไม่ได้รับสิทธิ์
|
||||
|
||||
#i นอกจากนี้ยังได้มีการทดสอบประสิทธิภาพของอุปกรณ์ในหลายด้าน เช่น ความสามารถในการอ่านค่า NFC
|
||||
จากอุปกรณ์หลายรูปแบบ ระยะการทำงานของเซนเซอร์
|
||||
ความถูกต้องในการตรวจสอบข้อมูลและความเสถียรของระบบ
|
||||
ผลการทดสอบแสดงให้เห็นว่าเครื่องมือที่พัฒนาขึ้นสามารถทำงานได้ตามวัตถุประสงค์
|
||||
สามารถยืนยันตัวตนได้อย่างถูกต้อง มีความรวดเร็วในการประมวลผล
|
||||
และช่วยลดโอกาสการบุกรุกจากบุคคลภายนอกได้จริง
|
||||
|
||||
#i จากผลการดำเนินงานสรุปได้ว่า เครื่องมือยืนยันตัวตนด้วย NFC
|
||||
ที่พัฒนาขึ้นสามารถนำไปประยุกต์ใช้ในด้านการรักษาความปลอดภัยได้หลากหลาย เช่น
|
||||
การควบคุมการเข้า–ออกห้องเรียน ห้องพัก ที่อยู่อาศัย หรือสถานที่ที่ต้องการจำกัดสิทธิ์การเข้าถึง
|
||||
โครงงานนี้จึงเป็นแนวทางหนึ่งในการพัฒนาระบบรักษาความปลอดภัยที่มีต้นทุนไม่สูง ใช้งานง่าย
|
||||
และสามารถต่อยอดพัฒนาเพิ่มเติมในอนาคต เช่นการเชื่อมต่อกับระบบแจ้งเตือนผ่านแอปพลิเคชัน
|
||||
การบันทึกประวัติผู้เข้าใช้งาน หรือการเพิ่มรูปแบบการยืนยันตัวตนร่วมกับเทคโนโลยีอื่น
|
||||
เพื่อเพิ่มประสิทธิภาพและความปลอดภัยให้ดียิ่งขึ้น
|
||||
|
||||
#pagebreak()
|
||||
|
||||
@@ -65,4 +88,32 @@
|
||||
|
||||
= Abstract
|
||||
|
||||
#i This project
|
||||
#i This project aims to study and apply NFC technology for identity
|
||||
verification, design and create tools for performing authorization, prevent
|
||||
invasion from an unauthorized personnel, and enhance the convenience of mobile
|
||||
phone authentication. The focus is on creating a system that is simple, fast,
|
||||
reliable, and suitable for practical application.
|
||||
|
||||
#i The project began by studying the operating principles of NFC sensors and
|
||||
related microcontrollers. Then, the circuit and structure of the device were
|
||||
designed accordingly. The developers developed a system capable of reading data
|
||||
from registered mobile devices or NFC cards. When a device is scanned, the
|
||||
system verifies the data against a database. If the data is correct, access is
|
||||
granted immediately. If incorrect, the system denies access to prevent
|
||||
unauthorized entry.
|
||||
|
||||
#i Furthermore, the device's performance was tested in several aspects, such as
|
||||
its ability to read NFC data from various devices, the sensor's operating range,
|
||||
verification accuracy, and system stability. The test results showed that the
|
||||
developed tool can function as intended, accurately verifying identities,
|
||||
processing data quickly and effectively reducing the potential for intrusion by
|
||||
unauthorized individuals.
|
||||
|
||||
#i From the project's results, it can be concluded that the developed NFC
|
||||
authentication tool can be applied in various security applications, such as
|
||||
controlling access to classrooms, dorm rooms, residences, or places requiring
|
||||
restricted access. This project therefore represents a pathway for developing a
|
||||
low-cost, easy-to-use security system that can be further improved upon in the
|
||||
future, such as connecting to an application-based notification system,
|
||||
recording user history, or adding authentication methods with other technologies
|
||||
to enhance efficiency and security.
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#i ผู้จัดทำขอขอบคุณครูที่ปรึกษาและครูที่ปรึกษาร่วม นายภาคิน เหรียญทอง และนายวสันต์ สารคำ ที่ได้ให้คำปรึกษาและคำแนะนำวิธีการในการจัดทำโครงงานให้แก่กลุ่มของข้าพเจ้า ช่วยให้ชิ้นงานสำเร็จลุล่วงตามจุดประสงค์ที่ได้ตั้งไว้อย่างราบรื่น และขอขอบคุณวิทยาลัยเทคนิคหนองคายที่ได้ให้โอกาศแก่กลุ่มของข้าพเจ้าในการประดิษฐ์เครื่องยืนยันตัวตนด้วยระบบ NFC นี้ขึ้นมา
|
||||
|
||||
#v(1em)
|
||||
|
||||
#align(right, grid(
|
||||
columns: 2,
|
||||
column-gutter: 1em,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#import "PageTemplate.typ": *
|
||||
#show: page-theme
|
||||
#show: chapter-page
|
||||
#set enum(
|
||||
indent: 3em,
|
||||
indent: 1.7em,
|
||||
numbering: n => context {
|
||||
return counter(heading).display() + "." + str(n)
|
||||
},
|
||||
@@ -14,11 +14,20 @@
|
||||
|
||||
== ที่มาและความสำคัญของปัญหา
|
||||
|
||||
#i ความปลอดภัยนั้นเป็นเรื่องสำคัญสำหรับทุกคนแต่องค์กรแต่ละองค์กรและคนแต่ละคนมักมีความต้องการด้านความปลอดภัยไม่เหมือนกัน แต่ในบางครั้ง เมื่อมีบุคคลหรือองค์กรที่ต้องการเทคโนโลยีด้านความปลอดภัยเหล่านี้ เทคโนโลยีความปลอดภัยนั้นอาจมีราคาสูงเกินกว่าจะเอื้อมถึงได้ ส่งผลให้อาจมีการลดระดับความปลอดภัยลงมา เพิ่มความเสี่ยงของชีวิต ทรัพย์สิน เอกสาร และข้อมูลต่าง ๆ ขององค์กรหรือบุคคลนั้น ๆ
|
||||
#h(1.7em)
|
||||
ความปลอดภัยนั้นเป็นเรื่องสำคัญสำหรับทุกคนแต่องค์กรแต่ละองค์กรและคนแต่ละคนมักมีความต้องการด้านความปลอดภัยไม่เหมือนกัน
|
||||
แต่ในบางครั้ง เมื่อมีบุคคลหรือองค์กรที่ต้องการเทคโนโลยีด้านความปลอดภัยเหล่านี้
|
||||
เทคโนโลยีความปลอดภัยนั้นอาจมีราคาสูงเกินกว่าจะเอื้อมถึงได้ ส่งผลให้อาจมีการลดระดับความปลอดภัยลงมา
|
||||
เพิ่มความเสี่ยงของชีวิต ทรัพย์สิน เอกสาร และข้อมูลต่าง ๆ ขององค์กรหรือบุคคลนั้น ๆ
|
||||
|
||||
#i ในโลกปัจจุบัน อินเทอร์เน็ตนั้นก็เป็นสิ่งที่สำคัญมากเช่นกัน และสถานที่ส่วนใหญ่มักจะมีอินเทอร์เน็ต จึงก่อให้เกิดการที่มีอุปกรณ์อินเทอร์เน็ตรอบตัวเพิ่มขึ้นทุกวัน และได้มีสิ่งที่เรียกว่า Internet of Things (IoT) เกิดขึ้น ซึ่งคืออุปกรณ์ที่ถูกปรับปรุงให้ใช้งานได้ดีขึ้นด้วยเทคโนโลยีไร้สายต่าง ๆ เช่น Wi-Fi, Bluetooth, Zigbee, และ Thread
|
||||
#h(1.7em) ในโลกปัจจุบัน อินเทอร์เน็ตนั้นก็เป็นสิ่งที่สำคัญมากเช่นกัน และสถานที่ส่วนใหญ่มักจะมีอินเทอร์เน็ต
|
||||
จึงก่อให้เกิดการที่มีอุปกรณ์อินเทอร์เน็ตรอบตัวเพิ่มขึ้นทุกวัน และได้มีสิ่งที่เรียกว่า Internet of Things
|
||||
(IoT) เกิดขึ้น ซึ่งคืออุปกรณ์ที่ถูกปรับปรุงให้ใช้งานได้ดีขึ้นด้วยเทคโนโลยีไร้สายต่าง ๆ เช่น#jb Wi-Fi,
|
||||
Bluetooth, Zigbee, และ Thread
|
||||
|
||||
#i โครงงานนี้จึงมีเป้าหมายที่จะแก้ไขปัญหาที่กล่าวไปข้างต้น พร้อมศึกษาและเรียนรู้เกี่ยวกับเทคโนโลยีไร้สาย Wi-Fi และ NFC เพื่อสร้างอุปกรณ์ยืนยันตัวตนที่ต้นทุนไม่สูงมากและให้ราคาเข้าถึงได้ง่ายขึ้น
|
||||
#h(1.7em) โครงงานนี้จึงมีเป้าหมายที่จะแก้ไขปัญหาที่กล่าวไปข้างต้น
|
||||
พร้อมศึกษาและเรียนรู้เกี่ยวกับเทคโนโลยีไร้สาย Wi-Fi และ NFC
|
||||
เพื่อสร้างอุปกรณ์ยืนยันตัวตนที่ต้นทุนไม่สูงมากและให้ราคาเข้าถึงได้ง่ายขึ้น
|
||||
|
||||
== วัตถุประสงค์ของโครงงาน
|
||||
|
||||
@@ -30,7 +39,7 @@
|
||||
== ประโยชน์ที่คาดว่าจะได้รับ
|
||||
|
||||
+ สามารถประยุกต์ความรู้ด้านอิเล็กทรอนิกส์และเทคโนโลยีมาใช้ในชีวิตประจำวันได้จริง
|
||||
+ สามารถตรวจจับผู้บุกรุกได้ ช่่วยเพื่อเพิ่มความไว้วางใจของบุคลากรในองค์กร
|
||||
+ สามารถตรวจจับผู้บุกรุกได้ ช่วยเพื่อเพิ่มความไว้วางใจของบุคลากรในองค์กร
|
||||
|
||||
== ขอบเขตของโครงงาน
|
||||
|
||||
@@ -40,9 +49,11 @@
|
||||
|
||||
== นิยามศัพท์เฉพาะ
|
||||
|
||||
#i เครื่องยืนยันตัวตนด้วย NFC คืออุปกรณ์ความปลอดภัยที่มีหน้าที่ในการยืนยันตัวตนบุคคลที่เข้าออกพื้นที่ โดยใช้เทคโนโลยี NFC เป็นระบบยืนยันตัวตนบุคคลและใช้เซนเซอร์ตรวจจับความเคลื่อนใหวในการตรวจสอบหากมีบุคคลเข้าไปโดยไม่ได้รับอนุญาต
|
||||
#h(1.7em) เครื่องยืนยันตัวตนด้วย NFC
|
||||
คืออุปกรณ์ความปลอดภัยที่มีหน้าที่ในการยืนยันตัวตนบุคคลที่เข้าออกพื้นที่ โดยใช้เทคโนโลยี NFC
|
||||
เป็นระบบยืนยันตัวตนบุคคลและใช้เซนเซอร์ตรวจจับความเคลื่อนไหวในการตรวจสอบหากมีบุคคลเข้าไปโดยไม่ได้รับอนุญาต
|
||||
|
||||
#pagebreak()
|
||||
#show: page-theme
|
||||
|
||||
== ผลที่คาดว่าจะได้รับ
|
||||
|
||||
|
||||
@@ -1,20 +1,30 @@
|
||||
#import "../PageTemplate.typ": i
|
||||
#import "../PageTemplate.typ": *
|
||||
|
||||
= ลำโพงสัญญาณ (Buzzer)
|
||||
|
||||
#i Buzzer เป็นอุปกรณ์ส่งสัญญาณเสียงซึ่งอาจเป็น อุปกรณ์ เชิงกลเครื่องกลไฟฟ้าหรือเพียโซอิเล็กทริก (เรียกสั้น ๆ ว่าเพียโซ) การใช้งานทั่วไปของบัซเซอร์และบี๊บเปอร์ ได้แก่อุปกรณ์แจ้งเตือนตัวตั้งเวลาวงจรและการยืนยันการป้อนข้อมูลของผู้ใช้ เช่น การคลิกเมาส์หรือการกดแป้นพิมพ์
|
||||
#h(1.70em) Buzzer เป็นอุปกรณ์ส่งสัญญาณเสียงซึ่งอาจเป็น อุปกรณ์ เชิงกลเครื่องกลไฟฟ้าหรือเพียโซอิเล็กทริก
|
||||
(เรียกสั้น ๆ ว่าเพียโซ) การใช้งานทั่วไปของบัซเซอร์และบี๊บเปอร์
|
||||
ได้แก่อุปกรณ์แจ้งเตือนตัวตั้งเวลาวงจรและการยืนยันการป้อนข้อมูลของผู้ใช้ เช่น
|
||||
การคลิกเมาส์หรือการกดแป้นพิมพ์
|
||||
|
||||
ประเภทของ Buzzer มี 3 ชนิด คือ
|
||||
|
||||
== ไฟฟ้าเชิงกล (Electromechanical)
|
||||
|
||||
#i อุปกรณ์ในยุคแรกๆ ใช้ระบบไฟฟ้าเครื่องกลแบบเดียวกับกระดิ่งไฟฟ้าโดยไม่มีฆ้องโลหะ ในทำนองเดียวกันรีเลย์อาจเชื่อมต่อเพื่อตัดกระแสไฟฟ้า ที่ทำหน้าที่สั่งการตัวเอง ซึ่งทำให้หน้าสัมผัสส่งเสียงหึ่งๆ (หน้าสัมผัสจะส่งเสียงหึ่งๆ ที่ความถี่สายหากใช้ไฟฟ้ากระแสสลับ) บ่อยครั้งที่อุปกรณ์เหล่านี้ถูกยึดไว้กับผนังหรือเพดานเพื่อใช้เป็นแผงเก็บเสียง คำว่า "buzzer" มาจากเสียงแหบๆ ของ buzzer ระบบไฟฟ้าเครื่องกล
|
||||
#iii อุปกรณ์ในยุคแรกๆ ใช้ระบบไฟฟ้าเครื่องกลแบบเดียวกับกระดิ่งไฟฟ้าโดยไม่มีฆ้องโลหะ
|
||||
ในทำนองเดียวกันรีเลย์อาจเชื่อมต่อเพื่อตัดกระแสไฟฟ้า ที่ทำหน้าที่สั่งการตัวเอง
|
||||
ซึ่งทำให้หน้าสัมผัสส่งเสียงหึ่งๆ (หน้าสัมผัสจะส่งเสียงหึ่งๆ ที่ความถี่สายหากใช้ไฟฟ้ากระแสสลับ)
|
||||
บ่อยครั้งที่อุปกรณ์เหล่านี้ถูกยึดไว้กับผนังหรือเพดานเพื่อใช้เป็นแผงเก็บเสียง คำว่า "buzzer"
|
||||
มาจากเสียงแหบๆ ของ buzzer ระบบไฟฟ้าเครื่องกล
|
||||
|
||||
== กลไก (Mechanical)
|
||||
|
||||
#i จอยบัซเซอร์เป็นตัวอย่างของบัซเซอร์แบบกลไกล้วนๆ และจำเป็นต้องมีไดรเวอร์ ตัวอย่างอื่นๆ ของบัซเซอร์ประเภทนี้คือกริ่งประตู
|
||||
#iii จอยบัซเซอร์เป็นตัวอย่างของบัซเซอร์แบบกลไกล้วนๆ และจำเป็นต้องมีไดรเวอร์ ตัวอย่างอื่นๆ
|
||||
ของบัซเซอร์ประเภทนี้คือกริ่งประตู
|
||||
|
||||
== เพียโซอิเล็กทริก (Piezoelectric)
|
||||
|
||||
#i องค์ประกอบเพียโซอิเล็กทริกอาจถูกขับเคลื่อนด้วย วงจรอิเล็กทรอนิกส์ แบบสั่นหรือ แหล่ง สัญญาณเสียง อื่นๆ ซึ่งขับเคลื่อนด้วยเครื่องขยายเสียงเพียโซอิเล็กทริกเสียงที่มักใช้เพื่อระบุว่ามีการกดปุ่ม ได้แก่ เสียงคลิก เสียงกริ่ง หรือเสียงบี๊บ
|
||||
#iii องค์ประกอบเพียโซอิเล็กทริกอาจถูกขับเคลื่อนด้วย วงจรอิเล็กทรอนิกส์ แบบสั่นหรือ แหล่ง สัญญาณเสียง
|
||||
อื่นๆ ซึ่งขับเคลื่อนด้วยเครื่องขยายเสียงเพียโซอิเล็กทริกเสียงที่มักใช้เพื่อระบุว่ามีการกดปุ่ม ได้แก่ เสียงคลิก
|
||||
เสียงกริ่ง หรือเสียงบี๊บ
|
||||
|
||||
|
||||
@@ -1,21 +1,46 @@
|
||||
#import "../PageTemplate.typ": page-theme
|
||||
#import "@preview/i-figured:0.2.4"
|
||||
// #show: page-theme
|
||||
|
||||
#show heading: i-figured.reset-counters.with(level: 3)
|
||||
#show figure: i-figured.show-figure.with(level: 3)
|
||||
|
||||
#set enum(numbering: "1)")
|
||||
#set heading(numbering: "บทที่ 1")
|
||||
#include "Intro.typ"
|
||||
|
||||
#[
|
||||
#show heading: it => {
|
||||
if it.level > 2 {
|
||||
block(
|
||||
it,
|
||||
inset: (left: 1.7em * (it.level - 2) + (0.9em * (it.level - 3))),
|
||||
)
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
|
||||
#include "Intro.typ"
|
||||
|
||||
#set heading(numbering: "1.1", offset: 1)
|
||||
#include "Microcontroller.typ"
|
||||
#include "Sensors.typ"
|
||||
#include "Buzzer.typ"
|
||||
#include "HTTP.typ"
|
||||
#include "HTTPS.typ"
|
||||
#include "TLS.typ"
|
||||
#include "NFC.typ"
|
||||
#include "Flutter.typ"
|
||||
#include "Git.typ"
|
||||
]
|
||||
|
||||
#show heading.where(level: 3): it => {
|
||||
block(
|
||||
it,
|
||||
inset: (left: 2.1em * (it.level - 2)),
|
||||
)
|
||||
}
|
||||
#show heading.where(level: 4): it => {
|
||||
block(
|
||||
it,
|
||||
inset: (left: 5.1em),
|
||||
)
|
||||
}
|
||||
|
||||
#set heading(numbering: "1.1", offset: 1)
|
||||
#include "Microcontroller.typ"
|
||||
#include "Sensors.typ"
|
||||
#include "Buzzer.typ"
|
||||
#include "HTTP.typ"
|
||||
#include "HTTPS.typ"
|
||||
#include "TLS.typ"
|
||||
#include "NFC.typ"
|
||||
#include "Flutter.typ"
|
||||
#include "Git.typ"
|
||||
#include "CLanguage.typ"
|
||||
|
||||
@@ -2,563 +2,251 @@
|
||||
#import "@preview/treet:1.0.0": *
|
||||
#import "@preview/tiaoma:0.3.0"
|
||||
#set heading(numbering: "1.1", offset: 1)
|
||||
#set figure(kind: image)
|
||||
|
||||
= Flutter <flutter>
|
||||
|
||||
#i Flutter เป็นชุดพัฒนาซอฟต์แวร์ UI แบบโอเพนซอร์สที่สร้างโดย Google
|
||||
#h(1.7em) Flutter เป็นชุดพัฒนาซอฟต์แวร์ UI แบบโอเพนซอร์สที่สร้างโดย Google
|
||||
สามารถใช้พัฒนาแอปพลิเคชันข้ามแพลตฟอร์มจากฐานโคดเดียวสำหรับเว็บ Fuchsia, Android, iOS,
|
||||
Linux, macOS และ Windows โดย Flutter ได้รับการพูดถึงครั้งแรกในปี 2015
|
||||
และเปิดตัวในเดือนพฤษภาคม 2017 และ Flutter ถูกใช้งานภายในโดย Google ในแอปพลิเคชันต่างๆ
|
||||
เช่น Google Pay และ Google Earth รวมถึงโดยนักพัฒนาซอฟต์แวร์รายอื่นๆ เช่น ByteDance
|
||||
และ Alibaba
|
||||
Linux, macOS และ#jb Windows โดย Flutter ได้รับการพูดถึงครั้งแรกในปี 2015
|
||||
และเปิดตัวในเดือนพฤษภาคม 2017 และ#jb Flutter ถูกใช้งานภายในโดย Google ในแอปพลิเคชันต่างๆ
|
||||
เช่น Google Pay และ Google Earth รวมถึงโดยนักพัฒนาซอฟต์แวร์รายอื่นๆ เช่น ByteDance และ
|
||||
Alibaba
|
||||
|
||||
#i Flutter จะสร้างแอปพลิเคชันที่มีเอ็นจิ้นการเรนเดอร์ของตัวเอง ซึ่งส่งข้อมูลพิกเซลไปยังหน้าจอโดยตรง
|
||||
ซึ่งแตกต่างจากเฟรมเวิร์ก UI อื่น ๆ อีกมากมายที่อาศัยแพลตฟอร์มเป้าหมายเพื่อจัดหาเอ็นจิ้นการเรนเดอร์
|
||||
เช่น แอป Android พื้นฐานที่ใช้ Android SDK ระดับอุปกรณ์ หรือ iOS SDK ที่ใช้ UI stack
|
||||
ในตัวของแพลตฟอร์มเป้าหมาย การควบคุมขั้นตอนการแสดงผลของ Flutter
|
||||
ช่วยลดความยุ่งยากในการรองรับหลายแพลตฟอร์ม เนื่องจากสามารถใช้โคด UI
|
||||
ที่เหมือนกันได้กับทุกแพลตฟอร์มเป้าหมาย
|
||||
|
||||
#pagebreak()
|
||||
|
||||
== การติดตั้งโปรแกรมเขียนโคด
|
||||
|
||||
#i จริง ๆ แล้วนั้น Flutter สามารถทำงานกับโปรแกรมเขียนโคดใดก็ได้ แต่มีโปรแกรมเหล่านี้ที่อาจมีประสบการณ์การพัฒนาที่ดีกว่าโปรแกรมอื่น:
|
||||
|
||||
- Visual Studio Code (VS Code)
|
||||
- Android Studio
|
||||
- JetBrains IntelliJ
|
||||
- Firebase Studio
|
||||
|
||||
#i โครงงานนี้ใช้โปรแกรมเขียนโคด Android Studio เป็นหลักเนื่องจากแอพลิเคชันโครงงานมี Android เป็นเป้าหมายหลัก และ Android SDK สามารถจัดการได้ง่ายกว่าใน Android Studio
|
||||
|
||||
=== Android Studio
|
||||
|
||||
#i Android Studio สามารถดาวน์โหลดได้ผ่าน https://developer.android.com/studio หรือสามารถถูกติดตั้งและจัดการผ่านแอพลิเคชัน JetBrains Toolbox ได้เช่นกัน (https://www.jetbrains.com/toolbox-app/)
|
||||
|
||||
== การติดตั้ง Flutter <flInstall>
|
||||
|
||||
#i การติดตั้ง Flutter สามารถทำได้สองวิธีด้วยกัน คือการติดตั้งผ่าน Visual Studio Code (VS Code) และการติดตั้งด้วยตนเอง โดยหากต้องการใช้ VS Code เป็นโปรแกรมเขียนโคดอยู่แล้ว สามารถติดตั้งผ่าน VS Code ได้เลย
|
||||
|
||||
#i แต่ก่อนอื่น ต้องทำการติดตั้งโปรแกรมและไลบรารีพื้นฐานที่จำเป็นสำหรับ Flutter ก่อน
|
||||
|
||||
=== การติดตั้งโปรแกรมและไลบรารีที่จำเป็น
|
||||
|
||||
==== Windows
|
||||
|
||||
#grid(
|
||||
columns: 2,
|
||||
column-gutter: 1em,
|
||||
[#i ในการพัฒนาซอฟต์แวร์บน Windows ด้วย Flutter คุณจำเป็นต้องติดตั้ง Git สำหรับ Windows ซึ่งคุณสามารถดูขั้นตอนการติดตั้งได้โดยการสแกน QR code ด้านข้าง หรือที่ https://git-scm.com/install/windows หรือเพียงแค่ใช้ WinGet ในการติดตั้งโดยการใช้คำสั่งด้านล่าง],
|
||||
tiaoma.qrcode("https://git-scm.com/install/windows", width: 1in, alt: "QR โคดสำหรับหน้าการติดตั้ง Git สำหรับ Windows"),
|
||||
)
|
||||
|
||||
```sh
|
||||
winget install --id Git.Git -e --source winget
|
||||
```
|
||||
|
||||
==== Linux
|
||||
|
||||
#i Flutter ใช้ไลบรารีดังต่อไปนี้ในขั้นตอนการพัฒนาแอพลิเคชันบน Linux (development dependencies; ยังไม่รวมไลบรารีและโปรแกรมที่ต้องมีในการสร้างแอพลิเคชัน _สำหรับ_ Linux)
|
||||
|
||||
#grid(
|
||||
columns: 2,
|
||||
column-gutter: 2in,
|
||||
[
|
||||
- curl
|
||||
- git
|
||||
- unzip
|
||||
],
|
||||
[
|
||||
- xz
|
||||
- zip
|
||||
- glu
|
||||
],
|
||||
)
|
||||
|
||||
หากต้องการคำสั่งในการติดตั้งแพคเกจเหล่านี้ โปรดดู@flLinuxDetails
|
||||
|
||||
==== macOS
|
||||
|
||||
#i จำเป็นต้องทำการติดตั้งเครื่องมือ command-line Xcode เพื่อเข้าถึงเครื่องมือที่ Flutter จำเป็นต้องใช้ รวมถึง Git
|
||||
|
||||
ในการดาวน์โหลดเครื่องมือ ใช้คำสั่งต่อไปนี้ในเทอร์มินัลที่คุณเลือก:
|
||||
|
||||
```sh
|
||||
xcode-select --install
|
||||
```
|
||||
|
||||
#i หากคุณไม่ได้ติดตั้งเครื่องมืออยู่แล้ว จะมีไดอะลอกเพื่อคอนเฟิร์มว่าคุณต้องการที่จะติดตั้งมัน กด *Install* และกด *Done* เมื่อทำการติดตั้งเสร็จสิ้นแล้ว
|
||||
|
||||
=== การติดตั้งผ่าน Visual Studio Code
|
||||
|
||||
1. เปิด VSCode
|
||||
2. ติดตั้งส่วนขยาย Flutter \
|
||||
อยู่ภายใต้ ID `Dart-Code.flutter` ทั้งบน Visual Studio Marketplace และ OpenVSX
|
||||
3. ติดตั้ง Flutter ด้วย VS Code
|
||||
+ เปิด Command Palette ด้วยเมนู *View* > *Command Palette* หรือกด Ctrl + Shift + P
|
||||
+ ใน Command Palette พิมพ์ `flutter`.
|
||||
+ เลือก *Flutter: New Project*
|
||||
+ VS Code จะให้คุณเลือก Flutter SDK บนคอมพิวเตอร์ของคุณ เลือก *Download SDK*
|
||||
+ เมือหน้าไดอะลอก *Select Folder for Flutter SDK* แสดงขึ้น เลือกสถานที่ที่คุณอยากติดตั้ง Flutter
|
||||
+ คลิก *Clone Flutter* \
|
||||
ในระหว่างการดาวน์โหลด VS Code จะแสดงการแจ้งเตือนนี้:
|
||||
```
|
||||
Downloading the Flutter SDK. This may take a few minutes.
|
||||
```
|
||||
การดาวน์โหลดนี้จะใช้เวลาสองสามนาที หากคุณเชื่อว่าการดาวน์โหลดหยุดชะงัก คุณสามารถคลิก *Cancel* แล้วเริ่มต้นการติดตั้งใหม่ได้
|
||||
+ คลิก *Add SDK to PATH* \
|
||||
เมื่อเสร็จสิ้น จะมีการแจ้งเตือน
|
||||
```
|
||||
The Flutter SDK was added to your PATH
|
||||
```
|
||||
+ VS Code อาจแสดงการแจ้งเตือนเกี่ยวกับการเก็บข้อมูลของ Google หากคุณยินยอม คลิก *OK*
|
||||
+ เพื่อความแน่ใจ กรุณาปิดเทอร์มินัลทุกหน้าต่างหรือรีสตาร์ท VS Code เพื่อให้แน่ใจว่า Flutter จะสามารถใช้ผ่านเทอร์มินัลได้
|
||||
4. เมื่อเสร็จสิ้น ใช้คำสั่ง `flutter doctor -v` ในเทอร์มินัลที่คุณเลือกเพื่อตรวจสอบการติดตั้ง Flutter ของคุณ \
|
||||
หากคำสั่งไม่เจอหรือเกิดข้อผิดพลาดขึ้น ตรวจสอบ https://docs.flutter.dev/install/troubleshoot สำหรับข้อมูลเพิ่มเติม
|
||||
|
||||
#pagebreak()
|
||||
|
||||
=== การติดตั้งด้วยตนเอง
|
||||
|
||||
#i แนะนำให้ทำตาม https://docs.flutter.dev/install/manual#install-flutter เนื่องจากกระบวนการนี้ต้องใช้ข้อมูลที่ใหม่ล่าสุด
|
||||
|
||||
1. ดาวน์โหลด Flutter (สามารถหาปุ่มดาวน์โหลดได้จากลิงก์ด้านบน)
|
||||
2. สร้างโฟลเดอร์สำหรับเก็บ Flutter SDK
|
||||
3. ทำการแตกไฟล์ที่ดาวน์โหลดมา
|
||||
4. เพิ่ม Flutter เข้าไปยัง PATH ของคุณ (วิธีการขึ้นอยู่กับระบบปฏิบัติการ)
|
||||
5. ยืนยันความถูกต้องของการติดตั้งของคุณด้วยคำสั่ง `flutter doctor -v`
|
||||
#h(1.7em) Flutter จะสร้างแอปพลิเคชันที่มีเอ็นจิ้นการเรนเดอร์ของตัวเอง
|
||||
ซึ่งส่งข้อมูลพิกเซลไปยังหน้าจอโดยตรง ซึ่งแตกต่างจากเฟรมเวิร์ก UI อื่น ๆ
|
||||
อีกมากมายที่อาศัยแพลตฟอร์มเป้าหมายเพื่อจัดหาเอ็นจิ้นการเรนเดอร์ เช่น แอป Android พื้นฐานที่ใช้
|
||||
Android SDK ระดับอุปกรณ์ หรือ iOS SDK ที่ใช้ UI stack ในตัวของแพลตฟอร์มเป้าหมาย
|
||||
การควบคุมขั้นตอนการแสดงผลของ Flutter ช่วยลดความยุ่งยากในการรองรับหลายแพลตฟอร์ม
|
||||
เนื่องจากสามารถใช้โคด UI ที่เหมือนกันได้กับทุกแพลตฟอร์มเป้าหมาย
|
||||
|
||||
== Dart
|
||||
|
||||
#i Dart เป็นภาษาโปรแกรมที่ออกแบบโดย Lars Bak และ Kasper Lund และพัฒนาโดย
|
||||
Google สามารถใช้พัฒนาแอปพลิเคชันบนเว็บ มือถือ เซิร์ฟเวอร์ และเดสก์ท็อปได้ และยังเป็นภาษาหลักที่ใช้ในการพัฒนาแอพลิเคชัน Flutter
|
||||
#h(4.2em) Dart เป็นภาษาโปรแกรมที่ออกแบบโดย Lars Bak และ Kasper Lund และพัฒนาโดย#jb
|
||||
Google สามารถใช้พัฒนาแอปพลิเคชันบนเว็บ มือถือ เซิร์ฟเวอร์ และเดสก์ท็อปได้
|
||||
และยังเป็นภาษาหลักที่ใช้ในการพัฒนาแอปพลิเคชัน Flutter
|
||||
|
||||
#i Dart เป็นภาษาเชิงวัตถุ อิงคลาส และรวบรวมขยะ (garbage-collection) ด้วยไวยากรณ์แบบ C สามารถคอมไพล์เป็นโค้ดเครื่อง JavaScript หรือ WebAssembly ได้ รองรับอินเทอร์เฟซ มิกซ์อิน คลาสนามธรรม เจเนอริกแบบรีไฟด์ และการอนุมานชนิดข้อมูล
|
||||
#h(4.2em) Dart เป็นภาษาเชิงวัตถุ อิงคลาส และรวบรวมขยะ (garbage-collection)
|
||||
ด้วยไวยากรณ์แบบ C สามารถคอมไพล์เป็นโค้ดเครื่อง JavaScript หรือ WebAssembly ได้
|
||||
รองรับอินเทอร์เฟซ มิกซ์อิน คลาสนามธรรม เจเนอริกแบบรีไฟด์ และการอนุมานชนิดข้อมูล
|
||||
|
||||
== การสร้างโปรเจกต์
|
||||
== สถาปัตยกรรม
|
||||
|
||||
#i ตั้งแต่หัวข้อนี้เป็นต้นไป จะเป็นข้อมูลสำหรับการทำงานกับ Android Studio เป็นหลักเนื่องจากเป็นโปรแกรมหลักที่ถูกใช้งานในการพัฒนาแอพลิเคชันโครงงานนี้
|
||||
|
||||
#i หากยังไม่ได้ติดตั้งปลั๊กอิน Flutter โปรดติดตั้งปลั๊กอินก่อน โดยหากอยู่ในหน้าต้อนรับ สามารถติดตั้งปลั๊กอินได้โดยการเข้าไปยังแท็บ *Plugins* หรือหากเปิดโปรเจกต์อื่นอยู่ สามารถเข้าถึงหน้าปลั๊กอินได้โดยการกดที่ไอคอนฟันเฟืองในแถบเครื่องมือ แล้วกด *Plugins...* หลังจากนั้น ในแท็บ *Marketplace* ของหน้าปลั๊กอิน ค้นหา *Flutter* (ผู้ผลิตปลั๊กอินคือ Google) แล้วกด *Install*
|
||||
#h(4.2em) Flutter ถูกออกแบบมาให้เป็นระบบแบบเลเยอร์ที่ต่อขยายได้
|
||||
ประกอบด้วยไลบรารีอิสระหลายชุดที่แต่ละชุดพึ่งพาเลเยอร์ที่อยู่ด้านล่าง
|
||||
ไม่มีเลเยอร์ใดที่มีสิทธิ์พิเศษในการเข้าถึงเลเยอร์ด้านล่าง
|
||||
และทุกส่วนของเฟรมเวิร์กถูกออกแบบมาให้เป็นตัวเลือกและสามารถทดแทนได้
|
||||
|
||||
#afigure(
|
||||
image("Flutter/homePage.png", width: 65%),
|
||||
attr: "ส่วนหนึ่งของโครงงาน, ศตคุณ อุตมะ, ภายใต้ CC BY-SA 4.0",
|
||||
alt: "หน้ายินดีต้อนรับในแท็บ Projects ที่กำลังแสดงรายการโปรเจกต์และปุ่มในการสร้างโปรเจกต์ใหม่",
|
||||
caption: [หน้ายินดีต้อนรับใน Android Studio],
|
||||
image("Flutter/archdiagram.png", width: 80%),
|
||||
attr: [Flutter, ภายใต้ CC BY 4.0],
|
||||
alt: "แผนผังสถาปัตยกรรม Flutter",
|
||||
caption: [สถาปัตยกรรม Flutter],
|
||||
)
|
||||
|
||||
#i เมื่อคลิก *New Flutter Project* จะมีหน้าถามสถานที่ติดตั้ง Flutter SDK หลังจากนั้น กด *Next* แล้วจะมีหน้าต่อไปนี้ขึ้นมาเพื่อให้คุณกรอกรายละเอียดโปรเจกต์
|
||||
#v(0.5em)
|
||||
|
||||
#afigure(
|
||||
image("Flutter/newProjectPage.png", width: 80%),
|
||||
attr: "ส่วนหนึ่งของโครงงาน, ศตคุณ อุตมะ, ภายใต้ CC BY-SA 4.0",
|
||||
alt: "หน้ากรอกรายละเอียดโปรเจกต์ใหม่",
|
||||
caption: [หน้าโปรเจกต์ใหม่],
|
||||
)
|
||||
#iii สำหรับระบบปฏิบัติการที่อยู่ภายใต้ แอปพลิเคชัน Flutter
|
||||
จะถูกบรรจุในลักษณะเดียวกับแอปพลิเคชันเนทีฟอื่น ๆ โดยตัวฝังตัว (Embedder)
|
||||
เฉพาะแพลตฟอร์มจะทำหน้าที่เป็นจุดเริ่มต้น#jb
|
||||
ประสานงานกับระบบปฏิบัติการที่อยู่ภายใต้เพื่อเข้าถึงบริการต่างๆ เช่น พื้นผิวการแสดงผล การเข้าถึง
|
||||
และการป้อนข้อมูล และจัดการลูปเหตุการณ์ข้อความ ตัวฝังตัวเขียนด้วยภาษาที่เหมาะสมกับแพลตฟอร์ม#jb
|
||||
ปัจจุบันคือ Java และ C++ สำหรับ Android, Swift และ Objective-C/Objective-C++ สำหรับ#jb
|
||||
iOS และ macOS และ C++ สำหรับ Windows และ Linux การใช้ตัวฝังตัว โค้ด Flutter
|
||||
สามารถรวมเข้ากับแอปพลิเคชันที่มีอยู่แล้วในรูปแบบโมดูล หรือโค้ดอาจเป็นเนื้อหาทั้งหมดของแอปพลิเคชันก็ได้
|
||||
Flutter มีตัวฝังตัวจำนวนมากสำหรับแพลตฟอร์มเป้าหมายทั่วไป แต่ก็ยังมีตัวฝังตัวอื่นๆ อีกด้วย
|
||||
|
||||
รายละเอียดที่จำเป็นต้องกรอกในการสร้างโปรเจกต์ใหม่มีดังนี้:
|
||||
#iii หัวใจหลักของ Flutter คือ Flutter engine ซึ่งส่วนใหญ่เขียนด้วยภาษา C++
|
||||
และรองรับฟังก์ชันพื้นฐานที่จำเป็นต่อการทำงานของแอปพลิเคชัน Flutter ทั้งหมด
|
||||
เอนจินนี้มีหน้าที่ในการแปลงฉากที่ประกอบขึ้นเป็นภาพแรสเตอร์ทุกครั้งที่จำเป็นต้องวาดเฟรมใหม่
|
||||
มันมีหน้าที่ให้การใช้งานระดับต่ำของ API หลักของ Flutter รวมถึงการจัดวางข้อความกราฟิก
|
||||
การรับส่งข้อมูลไฟล์และเครือข่าย รันไทม์ Dart และเครื่องมือคอมไพล์
|
||||
|
||||
- *Project name:* ชื่อโปรเจกต์
|
||||
- *Project location:* โฟลเดอร์ที่ต้องการเก็บโปรเจกต์
|
||||
- *Description:* รายละเอียดโปรเจกต์
|
||||
- *Project type:* ประเภทโปรเจกต์ ในกรณีนี้เป็นค่า *Application* เนื่องจากเราต้องการสร้างแอพลิเคชัน
|
||||
- *Organization:* โดเมนเนมย้อนหลังขององค์กรที่พัฒนา (Reverse domain name notation; Reverse-DNS)
|
||||
- *Android language:* เลือกระหว่าง Java และ Kotlin เป็นภาษาหลักที่ใช้ในแอพลิเคชัน Android
|
||||
- *Platforms:* แพลตฟอร์มที่โปรเจกต์จะรองรับ อย่างไรก็ตาม การสร้างไฟล์ไบนารีสำหรับแอพลิเคชันขึ้นอยู่กับแพลตฟอร์มที่พัฒนาแอพลิเคชันเช่นกัน หมายความว่า ถึงแม้ตามทฤษฎีแล้วแอพลิเคชันของคุณจะรองรับ iOS คุณต้องมีอุปกรณ์ Mac ในการสร้างไฟล์แอพลิเคชัน iOS ออกมา
|
||||
#iii เอนจินนี้ถูกเปิดเผยสู่เฟรมเวิร์ก Flutter ผ่านทาง dart:ui ซึ่งห่อหุ้มโค้ด C++
|
||||
ที่อยู่เบื้องหลังด้วยคลาส Dart ไลบรารีนี้เปิดเผยส่วนประกอบพื้นฐานระดับต่ำสุด เช่น
|
||||
คลาสสำหรับควบคุมระบบย่อยการรับข้อมูล กราฟิก และการแสดงผลข้อความ
|
||||
|
||||
เมื่อทำการใส่รายละเอียดทั้งหมดแล้ว สามารถกด Create เพื่อสร้างโปรเจกต์ได้เลย
|
||||
#iii โดยทั่วไป นักพัฒนาจะโต้ตอบกับ Flutter ผ่านเฟรมเวิร์ก Flutter
|
||||
ซึ่งเป็นเฟรมเวิร์กที่ทันสมัยและตอบสนองต่อสิ่งรอบข้าง เขียนด้วยภาษา Dart
|
||||
เฟรมเวิร์กนี้ประกอบด้วยชุดไลบรารี แพลตฟอร์ม#jb เลย์เอาต์ และพื้นฐานที่ครบครัน
|
||||
ซึ่งประกอบด้วยเลเยอร์หลายชั้น เริ่มจากล่างขึ้นบน ได้แก่
|
||||
|
||||
== แอพลิเคชันตัวอย่าง
|
||||
#[
|
||||
#set enum(indent: 4.1em)
|
||||
1. คลาสพื้นฐานและบริการส่วนประกอบต่างๆ เช่น แอนิเมชัน การวาดภาพ และท่าทางสัมผัส
|
||||
ซึ่งนำเสนอนามธรรมที่ใช้กันทั่วไปเหนือพื้นฐานที่อยู่เบื้องหลัง
|
||||
|
||||
เมื่อกดรันแอพลิเคชันด้วยไอคอน #box(image("Flutter/vscode_play.svg", alt: "Play"), baseline: 15%) (หรือ Shift+F10 ใน Android Studio) จะได้แอพลิเคชันดังรูปด้านล่างออกมา
|
||||
2. เลเยอร์การเรนเดอร์ให้นามธรรมสำหรับการจัดการเลย์เอาต์ ด้วยเลเยอร์นี้
|
||||
คุณสามารถสร้างโครงสร้างแบบต้นไม้ของวัตถุที่เรนเดอร์ได้ คุณสามารถจัดการวัตถุเหล่านี้แบบไดนามิก
|
||||
โดยโครงสร้างแบบต้นไม้จะอัปเดตเลย์เอาต์โดยอัตโนมัติเพื่อสะท้อนการเปลี่ยนแปลงของคุณ
|
||||
|
||||
#afigure(
|
||||
grid(
|
||||
columns: 2,
|
||||
align: horizon,
|
||||
image(
|
||||
"Flutter/mobileExampleApp.png",
|
||||
height: 2.5in,
|
||||
alt: "แอพลิเคชันมือถือ มีแถบสีม่วง ตัวเลขแสดงจำนวนครั้งที่กดปุ่มและปุ่มกดเพิ่มจำนวน",
|
||||
),
|
||||
image(
|
||||
"Flutter/desktopExampleApp.png",
|
||||
width: 90%,
|
||||
alt: "โปรแกรมคอมพิวเตอร์ แถบหน้าต่างโปรแกรมสีดำ ในหน้าต่างประกอบด้วยส่วนประกอบคล้ายแอพลิเคชันบนโทรศัพท์",
|
||||
),
|
||||
),
|
||||
attr: "ส่วนหนึ่งของโครงงาน, ศตคุณ อุตมะ, ภายใต้ CC BY-SA 4.0",
|
||||
caption: [แอพลิเคชันตัวอย่างบน Android 15 และ Arch Linux],
|
||||
)
|
||||
3. เลเยอร์วิดเจ็ตเป็นนามธรรมของการประกอบ
|
||||
วัตถุเรนเดอร์แต่ละชิ้นในเลเยอร์การเรนเดอร์จะมีคลาสที่สอดคล้องกันในเลเยอร์วิดเจ็ต นอกจากนี้
|
||||
เลเยอร์วิดเจ็ตยังช่วยให้คุณกำหนดการรวมกันของคลาสที่คุณสามารถนำกลับมาใช้ใหม่ได้
|
||||
นี่คือเลเยอร์ที่แนะนำโมเดลการเขียนโปรแกรมแบบตอบสนอง
|
||||
|
||||
#show raw.where(block: true): set block(below: 2em)
|
||||
|
||||
_*หมายเหตุ:* โคดในห้วข้อนี้ถูกนำ comment ออกเพื่อความรวบรัด_
|
||||
|
||||
ภายในโฟลเดอร์โปรเจกต์ใหม่ จะมีไฟล์ `lib/main.dart` พร้อมแอพลิเคชันตัวอย่าง
|
||||
|
||||
โดยในบรรทัดแรก จะมีการนำเข้า Material UI
|
||||
|
||||
```dart
|
||||
import 'package:flutter/material.dart';
|
||||
```
|
||||
|
||||
และถัดมา จะมีฟังก์ชันหลักชื่อ `main` ที่ทำหน้าที่ในการรันแอพลิเคชัน โดยมีการรับอาร์กิวเมนต์เป็นวิดเจ็ท ซึ่งในกรณีนี้เป็นการสร้างวัตถุจากคลาส `MyApp` ที่เป็นวิดเจ็ท
|
||||
|
||||
```dart
|
||||
void main() {
|
||||
runApp(const MyApp());
|
||||
}
|
||||
```
|
||||
|
||||
ถัดมาจะมีคลาส `MyApp` ที่สืบทอดมาจาก `StatelessWidget` ซึ่งคือคลาสสำหรับวิดเจ็ทที่ไร้สถานะ ("Stateless")
|
||||
|
||||
```dart
|
||||
class MyApp extends StatelessWidget {
|
||||
```
|
||||
|
||||
ซึ่งในคลาสจะมี constructor ที่สามารถรับค่าคีย์ได้:
|
||||
```dart
|
||||
const MyApp({super.key});
|
||||
```
|
||||
|
||||
และจะมีฟังก์ชันในการสร้างวิดเจ็ท ซึ่งฟังก์ชันนี้เป็นการสืบทอดฟังก์ชันมา สังเกตได้จาก `@override`
|
||||
|
||||
```dart
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
```
|
||||
|
||||
และในฟังก์ชันจะมีการสร้างวัตถุ MaterialApp ซึ่งมีหน้าที่ในการเก็บข้อมูลเกี่ยวกับแอพลิเคชัน Material UI รวมถึงข้อมูลเช่น ชื่อแอพลิเคชัน (`title`) และธีม (`theme`)
|
||||
|
||||
```dart
|
||||
return MaterialApp(
|
||||
title: 'Flutter Demo',
|
||||
```
|
||||
|
||||
โดยข้อมูลธีมนั้นถูกเก็บด้วยการสร้างวัตถุ `ThemeData`
|
||||
|
||||
```dart
|
||||
theme: ThemeData(
|
||||
```
|
||||
|
||||
และมีการสร้างธีมสีจากสีหลักโดยการใช้เมธอด `ColorScheme.fromSeed` แต่ในโคดด้านล่างนี้
|
||||
คลาส `ColorScheme` นั้นถูกอนุมานขึ้นมา โดยใน Dart 3.10 มีฟีเจอร์ "dot shorthands" ซึ่งเป็นทางลัดในการข้ามการเขียนชื่อคลาส ซึ่งชื่อคลาสสามารถถูกอนุมานขึ้นมาได้เนื่องจากอาร์กิวเมนต์ `colorScheme` นั้นคาดหวังค่าที่เป็นวัตถุจากคลาส `ColorScheme` อยู่แล้ว
|
||||
|
||||
```dart
|
||||
colorScheme: .fromSeed(seedColor: Colors.deepPurple),
|
||||
),
|
||||
```
|
||||
|
||||
และต่อมา อาร์กิวเมนต์ `home` เป็นอาร์กิวเมนต์ที่รับค่าเป็นวิดเจ็ทซึ่งจะเป็นหน้าแรกของแอพลิเคชัน
|
||||
|
||||
```dart
|
||||
home: const MyHomePage(title: 'Flutter Demo Home Page'),
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
ถัดมา มีการสร้างคลาส `MyHomePage` ที่ถูกใช้ด้านบน โดยคลาสเป็น `StatefulWidget` ซึ่งหมายความว่า เป็นคลาสที่มีสถานะ (State)
|
||||
|
||||
```dart
|
||||
class MyHomePage extends StatefulWidget {
|
||||
```
|
||||
|
||||
โดยใน constructor มีการรับค่าพารามีเตอร์ `title`
|
||||
|
||||
```dart
|
||||
const MyHomePage({super.key, required this.title});
|
||||
```
|
||||
|
||||
โดยคลาสนี้เป็นคลาสที่เก็บการตั้งค่าวิดเจ็ท และเป็นคลาสที่เก็บค่าพารามิเตอร์จากวิดเจ็ทที่เหนือกว่า และตัวแปรในคลาสย่อยของ `StatefulWidget` นั้นจะมีคีย์เวิร์ด `final` เสมอ ซึ่งหมายถึงว่า ตัวแปรนี้เปลี่ยนแปลงไม่ได้หลังจากสร้างวัตถุจากคลาสแล้ว
|
||||
|
||||
```dart
|
||||
final String title;
|
||||
```
|
||||
|
||||
ต่อมาจึงมีการสร้างวัตถุ State ซึ่งในฟังก์ชัน `createState` ที่ถูกสืบทอดมานั้น จะมีการสร้างวัตถุ State จากคลาส `_MyHomePageState` (โดยที่ `_` หมายถึงว่าคลาสนั้นเป็นส่วนตัวและไม่ควรถูกนำเข้าโดยไฟล์อื่น)
|
||||
|
||||
```dart
|
||||
@override
|
||||
State<MyHomePage> createState() => _MyHomePageState();
|
||||
}
|
||||
```
|
||||
|
||||
```dart
|
||||
class _MyHomePageState extends State<MyHomePage> {
|
||||
int _counter = 0;
|
||||
|
||||
void _incrementCounter() {
|
||||
```
|
||||
|
||||
โดยในฟังก์ชัน `_incrementCounter` มีการเรียกใช้ฟังก์ชัน `setState` ซึ่งจะแจ้งเตือน Flutter ว่ามีการเปลี่ยนแปลงสถานะ ซึ่งจะก่อให้เกิดการเร็นเดอร์วิดเจ็ทใหม่ และในอาร์กิวเมนต์ของ `setState` คือฟังก์ชันไม่ระบุชื่อ (anonymous functions หรืออีกชื่อหนึ่งคือ lambda) ที่เปลี่ยนแปลงสถานะของวิดเจ็ท
|
||||
|
||||
```dart
|
||||
setState(() {
|
||||
_counter++;
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
โดยต่อมา มีฟังก์ชัน `build` เช่นเคยที่มีหน้าที่ในการสร้างวิดเจ็ท โดยฟังก์ชัน `build` ของวิดเจ็ทที่มีสถานะนั้นจะถูกรันใหม่ทุกครั้งที่มีการเปลี่ยนแปลงสถานะ
|
||||
|
||||
```dart
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
```
|
||||
|
||||
*การทดลอง:* ในระหว่างที่รันแอพลิเคชันอยู่ ลองเปลี่ยนสีพื้นหลังของวิดเจ็ท `AppBar` (เป็นค่าอื่นเช่น `Colors.amber`) แล้วทำการ hot reload โดยการกดไอคอน#box(image("Flutter/flutterHotReload.svg", alt: "สายฟ้า", width: 1.5em), baseline: 20%)เพื่อเห็นการเปลี่ยนแปลงของสีแถบแอพลิเคชันในระหว่างที่สีของวิดเจ็ทอื่น ๆ ยังคงเดิม
|
||||
|
||||
```dart
|
||||
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
|
||||
```
|
||||
|
||||
โดยในอาร์กิวเมนต์ `title` นี้มีการใช้ค่าที่รับมาจากวิดเจ็ทที่เหนือกว่า โดย `widget` ในที่นี้คือวัตถุของคลาส `MyHomePage` ที่ทำหน้าที่เก็บค่า `title` ของเรา แล้วเราจึงทำค่า `title` นั้นใส่ในวิดเจ็ทข้อความ (`Text`)
|
||||
|
||||
```dart
|
||||
title: Text(widget.title),
|
||||
),
|
||||
```
|
||||
|
||||
`Center` เป็นวิดเจ็ทจัดเลย์เอาต์ โดยจะทำให้ลูก 1 วิดเจ็ทของมัน (`child`) อยู่ตรงกลาง
|
||||
|
||||
```dart
|
||||
body: Center(
|
||||
```
|
||||
|
||||
และ `Column` เป็นวิดเจ็ทจัดเลย์เอาต์เช่นกัน มันรับลูกหลายคน (`children`) แล้วจัดเรียงมันในแนวตั้ง โดยค่าเริ่มต้นแล้ว มันจะจัดให้ตัวเองกว้างเท่ากับลูก ๆ ของมัน และพยายามจัดให้ตัวเองสูงเท่าวิดเจ็ทที่สูงกว่า
|
||||
|
||||
วิดเจ็ทคอลัมน์มีหลายคุณสมบัติในการควบคุมขนาดของมันและการจัดวางลูก ๆ ของมัน โดยด้านล่างมีการใช้อาร์กิวเมนต์ `mainAxisAlignment` ในการจัดลูก ๆ ของมันให้อยู่ตรงกลางในแนวตั้ง โดย "main axis" หรือ แกนหลัก ในกรณีนี้คือแนวตั้ง เพราะคอลัมน์นั้นเป็นแนวตั้ง (และ "cross axis" หรือแกนไขว้ จะเป็นแนวนอน คือแนวตรงข้ามกับแนวหลัก)
|
||||
|
||||
```dart
|
||||
child: Column(
|
||||
mainAxisAlignment: .center,
|
||||
children: [
|
||||
const Text('You have pushed the button this many times:'),
|
||||
Text(
|
||||
'$_counter',
|
||||
```
|
||||
|
||||
การเข้าถึงธีมของแอพลิเคชัน (```dart Theme.of(context)```) แล้วนำธีมข้อความ `headlineMedium` มาใช้:
|
||||
|
||||
```dart
|
||||
style: Theme.of(context).textTheme.headlineMedium,
|
||||
), // Text
|
||||
],
|
||||
), // Column
|
||||
), // Center
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: _incrementCounter,
|
||||
tooltip: 'Increment',
|
||||
child: const Icon(Icons.add),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#pagebreak()
|
||||
|
||||
== โครงสร้างโปรเจกต์ Flutter <flStructure>
|
||||
|
||||
ในโครงงานนี้ โปรเจกต์ Flutter มีโครงสร้างคร่าว ๆ ดังกล่าว
|
||||
|
||||
#tree-list[
|
||||
- android
|
||||
- app
|
||||
- src
|
||||
- main
|
||||
- java: โคด Java
|
||||
- kotlin: โคด Kotlin
|
||||
- res: โฟลเดอร์ทรัพยากร เช่น ไอคอนแอพลิเคชัน
|
||||
- AndroidManifest.xml
|
||||
- build.gradle.kts
|
||||
- settings.gradle.kts
|
||||
- assets
|
||||
- certificates
|
||||
- rootCA.crt: ใบรับรอง Root (ดู@x509 สำหรับรายละเอียด)
|
||||
- build: โฟลเดอร์สำหรับเก็บไฟล์ไบนารี
|
||||
- ios
|
||||
- lib: ซอร์สโคดของแอพลิเคชัน
|
||||
- linux
|
||||
- macos
|
||||
- test
|
||||
- windows
|
||||
- l10n.yaml: ไฟล์ตั้งค่าฟีเจอร์แปลภาษา
|
||||
- pubspec.yaml: ไฟล์ข้อมูลโปรเจกต์ Flutter
|
||||
4. ไลบรารี Material และ Cupertino
|
||||
นำเสนอชุดควบคุมที่ครอบคลุมซึ่งใช้ส่วนประกอบพื้นฐานของเลเยอร์วิดเจ็ตเพื่อนำภาษาการออกแบบ
|
||||
Material หรือ iOS ไปใช้
|
||||
]
|
||||
|
||||
(รายการข้างต้นรวมถึงแค่ไฟล์ที่สำคัญที่จะถูกกล่าวถึงใน@flutter นี้)
|
||||
#iii เฟรมเวิร์ก Flutter มีขนาดค่อนข้างเล็ก
|
||||
ฟีเจอร์ระดับสูงหลายอย่างที่นักพัฒนาอาจใช้ถูกพัฒนาขึ้นมาในรูปแบบของแพ็กเกจ
|
||||
รวมถึงปลั๊กอินของแต่ละแพลตฟอร์ม เช่น กล้องและเว็บวิว ตลอดจนฟีเจอร์ที่ไม่ขึ้นกับแพลตฟอร์ม เช่น
|
||||
ตัวอักษร, HTTP และแอนิเมชัน ซึ่งสร้างขึ้นจากไลบรารีหลักของ Dart และ Flutter
|
||||
แพ็กเกจบางส่วนมาจากระบบนิเวศที่กว้างกว่า ครอบคลุมบริการต่างๆ เช่น การชำระเงินภายในแอป
|
||||
การตรวจสอบสิทธิ์ของ Apple และแอนิเมชัน
|
||||
|
||||
== การนำเข้าแพคเกจ
|
||||
== โครงสร้างของแอปพลิเคชัน
|
||||
|
||||
#i ไฟล์ `pubspec.yaml` เป็นไฟล์ที่เก็บข้อมูลเกี่ยวกับโปรเจกต์ Flutter ของคุณ เช่น ชื่อ คำอธิบาย เวอร์ชัน และรวมถึงสิ่งที่จะกล่าวถึงในหัวข้อนี้ คือการติดตั้งและนำเข้าแพคเกจภายนอกมาใช้ในโปรเจกต์
|
||||
#iii แผนภาพต่อไปนี้แสดงภาพรวมของส่วนประกอบต่างๆ ที่ประกอบกันเป็นแอป Flutter
|
||||
ทั่วไปที่สร้างขึ้นโดยคำสั่ง `flutter create` แผนภาพนี้แสดงตำแหน่งของ Flutter Engine
|
||||
ในโครงสร้างนี้ เน้นขอบเขตของ API และระบุที่เก็บโค้ด (repository) ที่ส่วนประกอบแต่ละส่วนอยู่
|
||||
คำอธิบายด้านล่างจะอธิบายคำศัพท์บางคำที่ใช้กันทั่วไปในการอธิบายส่วนประกอบของแอป Flutter
|
||||
|
||||
#i โดยหากไม่รวมรายละเอียดโปรเจกต์เบื้องต้นเช่นชื่อและคำอธิบายแล้ว ไฟล์ `pubspec.yaml` จะมีรายละเอียดดังนี้
|
||||
#afigure(
|
||||
image("Flutter/app-anatomy.svg", width: 2.5in),
|
||||
attr: [Flutter, ภายใต้ CC BY 4.0],
|
||||
alt: "เลเยอร์ต่าง ๆ ของแอพลิเคชัน Flutter ที่ถูกสร้างโดย flutter create",
|
||||
caption: [เลเยอร์ต่าง ๆ ของแอพลิเคชัน Flutter],
|
||||
)
|
||||
|
||||
`environment` นั้นจะกล่าวถึงสิ่งแวดล้อม ซึ่งในกรณีนี้มีเพียง `sdk` ที่ระบุเวอร์ชันของ Flutter SDK ในการคอมไพล์โปรเจกต์
|
||||
#[
|
||||
#set enum(indent: 7.55em)
|
||||
=== แอปพลิเคชัน Dart (Dart app)
|
||||
+ ประกอบวิดเจ็ตเข้าด้วยกันเพื่อสร้าง UI ที่ต้องการ
|
||||
+ ดำเนินการตามตรรกะทางธุรกิจ
|
||||
+ นักพัฒนาแอปเป็นเจ้าของ
|
||||
|
||||
```yaml
|
||||
environment:
|
||||
sdk: ^3.10.1
|
||||
```
|
||||
=== เฟรมเวิร์ก (Framework)
|
||||
1. ให้ API ระดับสูงสำหรับการสร้างแอปคุณภาพสูง (ตัวอย่างเช่น วิดเจ็ต การทดสอบการกด
|
||||
การตรวจจับท่าทาง การเข้าถึงได้ และการอินพุต ข้อความ)
|
||||
2. ประกอบต้นวิดเจ็ตของแอปพลิเคชันเป็นฉาก
|
||||
|
||||
`dependencies` จะกล่าวถึงไลบรารีที่โปรเจกต์พึ่งพา ซึ่งโดยค่าเริ่มต้นแล้ว ในโปรเจกต์ตัวอย่างจะมีการติดตั้งเซ็ทไอคอน Cupertino มาให้ (`cupertino_icons`; หรือเรียกอย่างง่ายว่า ไอคอน iOS) ซึ่งแน่นอนว่าหากคุณไม่ใช้ สามารถลบทิ้งได้
|
||||
=== เอนจิน (Engine)
|
||||
1. มีหน้าที่แปลงฉากเป็นรูปแบบแรสเตอร์
|
||||
2. ให้การทำงานระดับต่ำของแกนกลางของ Flutter API (เช่น กราฟิก การจัดข้อความ และรันไทม์
|
||||
Dart)
|
||||
3. เปิดเผยฟังก์ชันระดับนี้ให้แก่เฟรมเวิร์กผ่าน API `dart:ui`
|
||||
4. บูรณาการกับแพลตฟอร์มต่าง ๆ ด้วย API ตัวฝังตัว
|
||||
|
||||
```yaml
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
=== ตัวฝังตัว (Embedder)
|
||||
1. ประสานงานกับระบบปฏิบัติการภายใต้สำหรับการเข้าถึงบริการต่าง ๆ เช่น พื้นผิวการเรนเดอร์
|
||||
การเข้าถึง และการป้อนข้อมูล
|
||||
2. จัดการลูปอิเวนต์
|
||||
3. เปิดเผย API เฉพาะแพลตฟอร์มเพื่อบูรณาการตัวฝังตัวเข้าไปยังแอป
|
||||
|
||||
cupertino_icons: ^1.0.8
|
||||
```
|
||||
|
||||
`dev_dependencies` กล่าวถึงไลบรารีที่โปรเจกต์พึ่งพา#emph([ในการพัฒนา]) หมายความว่า ไลบรารีเหล่านี้จะไม่ถูกใส่เข้าไปยังแอพลิเคชันของคุณโดยตรง โดยตามค่าเริ่มต้นแล้ว จะมีแพคเกจ `flutter_test` ที่ถูกดึงมาจาก Flutter SDK โดยตรง และมี `flutter_lints` สำหรับการตรวจข้อผิดพลาดในโคด
|
||||
|
||||
```yaml
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
||||
flutter_lints: ^6.0.0
|
||||
```
|
||||
|
||||
`flutter` เป็นการตั้งค่าเกี่ยวกับ Flutter โดยที่ตามค่าเริ่มต้นแล้วจะมีค่า `uses-material-design` มาให้เป็น `true` ซึ่งจะเป็นการบอกกับ Flutter ว่าแอพลิเคชันนั้นใช้ Material design
|
||||
|
||||
```yaml
|
||||
flutter:
|
||||
uses-material-design: true
|
||||
```
|
||||
|
||||
และนอกจากนั้นแล้ว ในส่วนของ `flutter` นี้จะเป็นส่วนที่ลิสต์รายการไฟล์เพิ่มเติมที่ต้องการใส่เข้าไปในแอพลิเคชันด้วยเช่นกัน ตัวอย่างเช่น โครงงานนี้มีการเพิ่มเติมในส่วน `flutter` ดังนี้:
|
||||
|
||||
```yaml
|
||||
assets:
|
||||
- assets/certificates/rootCA.crt
|
||||
```
|
||||
|
||||
โดยจะเป็นการเพิ่มไฟล์ใบรับรอง `rootCA.crt` เข้าไปกับแอพลิเคชันเพื่อใช้ในการส่งคำขอ HTTPS ไปยังอุปกรณ์ของโครงงาน
|
||||
|
||||
#pagebreak()
|
||||
=== ตัวรัน (Runner)
|
||||
1. ประกอบชิ้นส่วนที่ถูกเปิดเผยโดยตัวฝังตัวเข้าเป็นแพคเกจแอปพลิเคชันที่สามารถใช้งานได้บนแพลตฟอร์มเป้าหมาย
|
||||
2. บางส่วนถูกสร้างขึ้นโดย `flutter create` และมีเจ้าของเป็นผู้พัฒนาแอป
|
||||
]
|
||||
|
||||
== ระบบการดีไซน์
|
||||
|
||||
โดยใน Flutter แล้วนั้น ไม่รวมแพคเกจบุคคลที่สาม จะมีระบบการดีไซน์อยู่สองแบบคือ:
|
||||
#iii โดยใน Flutter แล้วนั้น ไม่รวมแพคเกจบุคคลที่สาม จะมีระบบการดีไซน์อยู่สองแบบคือ:
|
||||
|
||||
+ Material Design: การดีไซน์ของ Google สำหรับ Android
|
||||
+ Cupertino Design: การดีไซน์ของ Apple สำหรับ iOS
|
||||
#[
|
||||
#set enum(indent: 4.10em)
|
||||
+ Material Design คือการดีไซน์ของ Google สำหรับ Android
|
||||
+ Cupertino Design คือการดีไซน์ของ Apple สำหรับ iOS
|
||||
]
|
||||
|
||||
*หมายเหตุ:* Cupertino Design ถูกแทนที่โดย Liquid Glass แล้ว โดยในปัจจุบันทีม Flutter กำลังทำการตรวจสอบและแก้ไขโครงสร้างระบบดีไซน์ ดังนั้น หากมีผู้พัฒนาต้องการใช้เอฟเฟกต์ Liquid Glass ในแอพลิเคชัน Flutter จึงจำเป็นต้องพึงพาแพคเกจบุคคลที่สามก่อนในขณะนี้ (Flutter เวอร์ชัน 3.38.3 ณ เวลาที่พิมพ์)
|
||||
#iii อย่างไรก็ตาม Cupertino Design ถูกแทนที่โดย Liquid Glass แล้ว โดยในปัจจุบันทีม Flutter
|
||||
กำลังทำการตรวจสอบและแก้ไขโครงสร้างระบบดีไซน์ ดังนั้น หากมีผู้พัฒนาต้องการใช้เอฟเฟกต์#jb Liquid
|
||||
Glass ในแอปพลิเคชัน Flutter จึงจำเป็นต้องพึงพาแพคเกจบุคคลที่สามก่อนในขณะนี้ (Flutter เวอร์ชัน
|
||||
3.38.5 ณ เวลาที่พิมพ์)
|
||||
|
||||
#i แอพลิเคชันในโครงงานนี้ใช้ Material Design เนื่องจากมีเป้าหมายหลักเป็นแพลตฟอร์ม Android โดย Material Design คือภาษาการดีไซน์ที่ถูกพัฒนาโดย Google และถูกเปิดตัวครั้งแรก 25 มิถุนายน 2014 และมีเวอร์ชันหลัก 3 เวอร์ชันด้วยกัน โดยที่เวอร์ชันที่ 3 ถูกเปิดตัวในงาน Google I/O 2021 และมีชื่อว่า "Material You" (แต่ชื่อธรรมดา "Material Design 3" ก็ยังถูกใช้งานกันอย่างปกติ) และในงาน Google I/O 2025 มีการเปิดตัว "Material 3 Expressive" ซึ่งเป็นการปรับปรุงต่อจาก Material You เดิมสำหรับ Android 16 และ Wear OS 6 และสามารถดูรายละเอียดเพิ่มเติมเกี่ยวกับ Material 3 ได้ที่ https://m3.material.io/
|
||||
#iii Material Design คือภาษาการดีไซน์ที่ถูกพัฒนาโดย Google และถูกเปิดตัวครั้งแรก 25 มิถุนายน
|
||||
2014 และมีเวอร์ชันหลัก 3 เวอร์ชันด้วยกัน โดยที่เวอร์ชันที่ 3 ถูกเปิดตัวในงาน Google I/O 2021
|
||||
และมีชื่อว่า "Material You" (แต่ชื่อธรรมดา "Material Design 3" ก็ยังถูกใช้งานกันอย่างปกติ)#jb
|
||||
และในงาน Google I/O 2025 มีการเปิดตัว "Material 3 Expressive"
|
||||
ซึ่งเป็นการปรับปรุงต่อจาก#jb Material You เดิมสำหรับ Android 16 และ Wear OS 6
|
||||
และสามารถดูรายละเอียดเพิ่มเติมเกี่ยวกับ Material 3 ได้ที่ https://m3.material.io/
|
||||
|
||||
== ข้อมูลเกี่ยวกับแพลตฟอร์ม
|
||||
== ส่วนติดต่อผู้ใช้ที่มีปฏิกิริยา
|
||||
|
||||
=== Android <flAndroid>
|
||||
#iii บนพื้นผิว Flutter เป็นเฟรมเวิร์ก UI แบบ reactive และ declarative
|
||||
ซึ่งนักพัฒนาเป็นผู้จัดเตรียมการแมปจากสถานะแอปพลิเคชันไปยังสถานะอินเทอร์เฟซ
|
||||
และเฟรมเวิร์กจะทำหน้าที่อัปเดตอินเทอร์เฟซขณะรันไทม์เมื่อสถานะของแอปพลิเคชันเปลี่ยนแปลง
|
||||
โมเดลนี้ได้รับแรงบันดาลใจจากงานที่มาจาก Facebook สำหรับเฟรมเวิร์ก React ของพวกเขา
|
||||
ซึ่งรวมถึงการทบทวนหลักการออกแบบแบบดั้งเดิมหลายประการ
|
||||
|
||||
#i ในการพัฒนาแอพลิเคชัน Android โดยใช้เฟรมเวิร์ก Flutter จำเป็นต้องใช้ส่วนประกอบเครื่องมือพัฒนา Android ดังนี้
|
||||
#iii ในเฟรมเวิร์ก UI แบบดั้งเดิมส่วนใหญ่ สถานะเริ่มต้นของอินเทอร์เฟซผู้ใช้จะถูกอธิบายเพียงครั้งเดียว
|
||||
จากนั้นจึงอัปเดตแยกกันด้วยโคดผู้ใช้ ณ รันไทม์ เพื่อตอบสนองต่อเหตุการณ์
|
||||
ความท้าทายประการหนึ่งของแนวทางนี้คือ เมื่อแอปพลิเคชันมีความซับซ้อนมากขึ้น
|
||||
นักพัฒนาจำเป็นต้องทราบว่าสถานะเปลี่ยนแปลงไปอย่างไรตลอดทั้ง UI ตัวอย่างเช่น พิจารณา UI ต่อไปนี้:
|
||||
|
||||
- Android SDK (API Level 36 ณ เวลาที่พิมพ์)
|
||||
- Android SDK Build-Tools
|
||||
- Android SDK Command-line Tools
|
||||
- Android SDK Platform-Tools
|
||||
- Android Emulator (ไม่บังคับ)
|
||||
|
||||
และแนะนำให้จัดการและติดตั้งเครื่องมือเหล่านี้ผ่าน Android Studio
|
||||
|
||||
#i ในการติดตั้ง Android SDK ควรติดตั้ง Android SDK ล่าสุดถึงแม้ว่าอุปกรณ์ของคุณจะใช้เวอร์ชันที่เก่ากว่านั้น เพื่อความมั่นใจว่าแอพลิเคชันจะสามารถใช้กับอุปกรณ์ที่ใหม่ล่าสุดได้
|
||||
|
||||
#i แอพลิเคชัน Android จะมี SDK/API level เป้าหมาย (Target SDK/API level) และ SDK/API level ขั้นต่ำ (Minimum SDK/API level) โครงงานนี้ ณ เวลาที่พิมพ์ ใช้ API level เป้าหมาย 36 (Android 16) และ API level ขั้นต่ำ 24 (Android 7) ซึ่งรวมกันแล้ว แอพลิเคชัน Android จะสามารถติดตั้งได้บนระบบตั้งแต่ API level ขั้นต่ำจนถึง API level เป้าหมาย หรือก็คือ แอพลิเคชันในโครงงานนี้สามารถติดตั้งได้ตั้งแต่บนระบบ Android 7 ถึง Android 16 นั่นเอง
|
||||
|
||||
==== Java/Kotlin
|
||||
|
||||
#i Java และ Kotlin เป็นภาษาสำคัญสำหรับการพัฒนาแอพลิเคชัน Android ถึงอย่างไรก็ตาม แอพลิเคชัน Flutter นั้นถูกเขียนด้วยภาษา Dart แต่ยังจำเป็นต้องมีโคด Java และ Kotlin เล็กน้อยเพื่อเริ่มต้นแอพลิเคชัน Flutter
|
||||
|
||||
#i โดยปกติแล้ว Flutter จะสร้างโคดพื้นฐานขึ้นมาให้สำหรับการเริ่มแอพลิเคชันแบบพื้นฐาน (อยู่ภายในโฟลเดอร์ `java` และ `kotlin` ตามที่ถูกกล่าวถึงใน@flStructure) ดังนั้นจึงไม่จำเป็นต้องมีการเขียนโคด Java หรือ Kotlin เอง แต่ในบางกรณี อาจต้องเขียนโคดเพิ่มเองหากมีความต้องการเข้าถึงฟีเจอร์พื้นฐานระบบที่ Flutter ไม่มี API เพื่อให้เข้าถึงได้และไม่มีแพคเกจเพื่อรองรับฟีเจอร์ที่ต้องการ
|
||||
|
||||
#i โครงการนี้ใช้ Java 21 (JetBrains Runtime/Azul Zulu OpenJDK) เป็นหลักในการทำงานกับ Gradle แต่แอพลิเคชัน Android ที่ผลิตออกมานั้น เพื่อให้เข้ากับเวอร์ชันที่เก่ากว่าของระบบปฏิบัติการได้ ใช้ Java 11
|
||||
|
||||
==== Gradle
|
||||
|
||||
#i Gradle เป็นเครื่องมือสร้างระบบอัตโนมัติสำหรับการพัฒนาซอฟต์แวร์หลายภาษา จัดการงานต่าง ๆ เช่น การคอมไพล์ การแพ็คเกจ การทดสอบ การปรับใช้ และการเผยแพร่ ภาษาที่รองรับ ได้แก่ Java (รวมถึงภาษา Kotlin, Groovy, Scala ที่ใช้ JDK), C/C++ และ JavaScript Gradle พัฒนาต่อยอดจากแนวคิดของ Apache Ant และ Apache Maven และนำเสนอภาษาเฉพาะโดเมนที่ใช้ Groovy และ Kotlin ซึ่งต่างจากการกำหนดค่าโครงการที่ใช้ XML ที่ Maven ใช้ Gradle ใช้กราฟแบบอะไซคลิกกำกับทิศทางเพื่อจัดการการอ้างอิง กราฟนี้ใช้เพื่อกำหนดลำดับของงานที่ควรดำเนินการ Gradle ทำงานบน Java Virtual Machine
|
||||
|
||||
#i Gradle คือเครื่องมือหลักที่ใช้ในการจัดการโปรเจกต์ Java ส่วนใหญ่ รวมถึงโปรเจกต์ Android โดยในโครงการนี้ จะใช้ Gradle เวอร์ชัน 8.14.3 เป็นหลัก
|
||||
|
||||
#i โดยปกติแล้ว ผู้พัฒนานั้นไม่มีความจำเป็นที่จะต้องแตะต้อง Gradle ด้วยตนเอง และ Flutter จะทำการจัดการเอง แต่หากมีความจำเป็นต้องใช้คำสั่ง Gradle ด้วยตนเอง จะมีสคริปต์ `gradlew` (หรือ `gradlew.bat` สำหรับผู้ใช้ Windows) ภายในโฟลเดอร์ `android` ของโปรเจกต์ Flutter เสมอเพื่อเรียกใช้ Gradle ที่ถูกดาวน์โหลดมาสำหรับโปรเจกต์นั้น ๆ
|
||||
|
||||
=== Linux <flLinuxDetails>
|
||||
|
||||
#i เช่นเดียวกับ Android ที่กล่าวไปข้างต้น Flutter มีการสร้างโคดสำหรับการเปิดแอพลิเคชันแบบพื้นฐาน แต่สำหรับ Linux แล้วนั้น Flutter ใช้โคด C++ และเฟรมเวิร์ก CMake ในการสร้างรากฐานของแอพลิเคชัน
|
||||
|
||||
#i ในการพัฒนาแอพลิเคชันสำหรับ Linux ต้องติดตั้งโปรแกรมเพิ่มเติม (build dependencies) ขยายความคือ ด้านบนคือสิ่งที่จำเป็นหากมีระบบอื่นเป็นเป้าหมาย แต่หากต้องการพัฒนาแอพลิเคชัน Linux ต้องติดตั้งโปรแกรมในรายการด้านล่างเพิ่ม
|
||||
|
||||
#grid(
|
||||
columns: 2,
|
||||
column-gutter: 1in,
|
||||
[
|
||||
- GTK 3 (ไลบรารีสำหรับการพัฒนา)
|
||||
- pkg-config
|
||||
- ไลบรารี GNU Standard C++ v3
|
||||
],
|
||||
[
|
||||
- Clang
|
||||
- CMake
|
||||
- Ninja
|
||||
],
|
||||
#afigure(
|
||||
image("Flutter/color-picker.png", width: 70%),
|
||||
alt: "หน้าต่างเลือกสี",
|
||||
caption: [หน้าต่างเลือกสี],
|
||||
)
|
||||
|
||||
#i การติดตั้งไลบรารีและโปรแกรมที่กล่าวไปข้างต้นจะแตกต่างกันไปแต่ละการแจกจ่าย Linux และ Flutter ใช้ไลบรารีพื้นฐานดังกล่าวในการทำงานของแอพลิเคชัน (runtime dependencies)
|
||||
#v(0.5em)
|
||||
|
||||
- GTK 3
|
||||
- blkid
|
||||
- LZMA
|
||||
#iii มีหลายที่ที่สามารถเปลี่ยนสถานะได้ กล่องสี, แถบเลื่อนเฉดสี, ปุ่มตัวเลือก เมื่อผู้ใช้โต้ตอบกับ UI
|
||||
การเปลี่ยนแปลงจะต้องสะท้อนให้เห็นในทุกที่ ที่เลวร้ายยิ่งกว่านั้น เว้นแต่จะได้รับการดูแล
|
||||
การเปลี่ยนแปลงเล็กน้อยในส่วนใดส่วนหนึ่งของอินเทอร์เฟซผู้ใช้อาจทำให้เกิดเอฟเฟกต์คลื่นส่งผลกระทบกับโค้ดที่ดูเหมือนจะไม่เกี่ยวข้องกัน
|
||||
|
||||
แต่โดยทั่วไปแล้ว ไลบรารีเหล่านี้ควรถูกติดตั้งมาอยู่แล้วหากคุณใช้ graphical desktop ทั่วไป
|
||||
#iii วิธีแก้ปัญหาอย่างหนึ่งคือแนวทางเช่น MVC
|
||||
โดยที่คุณส่งข้อมูลการเปลี่ยนแปลงไปยังโมเดลผ่านคอนโทรลเลอร์
|
||||
จากนั้นโมเดลจะพุชสถานะใหม่ไปยังมุมมองผ่านคอนโทรลเลอร์ อย่างไรก็ตาม#jb สิ่งนี้ก็เป็นปัญหาเช่นกัน
|
||||
เนื่องจากการสร้างและการอัปเดตองค์ประกอบ UI
|
||||
เป็นขั้นตอนสองขั้นตอนที่แยกจากกันซึ่งอาจไม่ซิงค์กันได้อย่างง่ายดาย
|
||||
|
||||
==== Debian
|
||||
#iii Flutter พร้อมด้วยเฟรมเวิร์กเชิงโต้ตอบอื่น ๆ ใช้แนวทางอื่นในการแก้ไขปัญหานี้
|
||||
โดยแยกอินเทอร์เฟซผู้ใช้ออกจากสถานะพื้นฐานอย่างชัดเจน ด้วย API สไตล์ React
|
||||
คุณจะสร้างเฉพาะคำอธิบาย UI เท่านั้น
|
||||
และเฟรมเวิร์กจะดูแลการใช้การกำหนดค่านั้นเพื่อสร้างหรืออัปเดตอินเทอร์เฟซผู้ใช้ตามความเหมาะสม
|
||||
|
||||
```sh
|
||||
# Development dependencies:
|
||||
sudo apt install curl git unzip xz-utils zip libglu1-mesa
|
||||
#iii ใน Flutter วิดเจ็ต (คล้ายกับส่วนประกอบใน React)
|
||||
จะแสดงด้วยคลาสที่ไม่เปลี่ยนรูปซึ่งใช้ในการกำหนดค่าแผนผังของวัตถุ
|
||||
วิดเจ็ตเหล่านี้ถูกใช้เพื่อจัดการแผนผังวัตถุที่แยกจากกันสำหรับโครงร่าง
|
||||
ซึ่งจากนั้นจะใช้ในการจัดการแผนผังวัตถุที่แยกจากกันสำหรับการประกอบ หัวใจหลักของ Flutter
|
||||
คือชุดของกลไกในการอัพเดทส่วนที่ดัดแปลงของแผนผังวิดเจ็ตอย่างมีประสิทธิภาพ
|
||||
การแปลงแผนผังหลายแผนผังของวัตถุให้เป็นแผนผังระดับล่างของวัตถุ
|
||||
และการแพร่กระจายการเปลี่ยนแปลงไปยังแผนผังวิดเจ็ตเหล่านี้
|
||||
|
||||
# Linux build dependencies:
|
||||
sudo apt install clang cmake ninja-build pkg-config libgtk-3-dev libstdc++-12-dev
|
||||
#iii วิดเจ็ตประกาศส่วนติดต่อผู้ใช้โดยการเขียนทับเมธอด `build()` ซึ่งเป็นฟังก์ชันที่แปลงสถานะเป็น UI
|
||||
|
||||
# Runtime dependencies:
|
||||
sudo apt install libgtk-3-0 libblkid1 liblzma5
|
||||
```
|
||||
#afigure(
|
||||
```
|
||||
UI = f(state)
|
||||
```,
|
||||
kind: image,
|
||||
caption: [สูตรแสดงการทำงานอย่างคร่าว],
|
||||
)
|
||||
|
||||
==== Fedora Linux
|
||||
#iii เมธอด `build()` นั้นตามการออกแบบแล้วเป็นเมธอดที่เร็วและควรที่จะไม่มีผลข้างเคียง
|
||||
ทำให้เมธอดนั้นสามารถถูกเรียกใช้โดยเฟรมเวิร์กเมื่อไหร่ก็ได้ที่จำเป็น
|
||||
(เป็นไปได้ที่จะบ่อยมากและมีการเรียกใช้หนึ่งครั้งต่อหนึ่งเฟรม)
|
||||
|
||||
```sh
|
||||
# Development dependencies:
|
||||
sudo dnf install curl git unzip xz zip mesa-libglu
|
||||
#iii วิธีนี้พึ่งพาลักษณะเฉพาะรันไทม์ภาษา (หากเจาะจงคือการสร้างและทำลายวัตถุอย่างรวดเร็ว)#jb ซึ่ง
|
||||
Dart นั้นเหมาะสำหรับงานนี้เป็นพิเศษ
|
||||
|
||||
# Linux build dependencies:
|
||||
sudo dnf install clang cmake ninja-build pkgconf gtk3
|
||||
== ประวัติ
|
||||
|
||||
# Runtime dependencies:
|
||||
sudo dnf install gtk3 libblkid xz
|
||||
```
|
||||
#iii Flutter เวอร์ชันแรกรู้จักกันในชื่อ "Sky" และทำงานบนระบบปฏิบัติการ Android
|
||||
มีการเปิดเผยในการประชุมสุดยอดนักพัฒนา Dart ประจำปี 2015
|
||||
โดยมีจุดประสงค์ที่ระบุไว้คือสามารถแสดงผลได้อย่างสม่ำเสมอที่ 120 เฟรมต่อวินาที เมื่อวันที่ 4 ธันวาคม
|
||||
2018 Flutter 1.0 เปิดตัวในการประชุม Flutter ที่ลอนดอน
|
||||
|
||||
==== Arch Linux
|
||||
#iii ในวันที่ 6 พฤษภาคม 2020 ชุดพัฒนาซอฟต์แวร์ (SDK) Dart เวอร์ชัน 2.8 และ Flutter 1.17.0
|
||||
ได้รับการเผยแพร่ โดยเพิ่มการรองรับ Metal API
|
||||
|
||||
```sh
|
||||
# Development dependencies:
|
||||
sudo pacman -S --needed curl git unzip xz zip glu
|
||||
#iii เมื่อวันที่ 3 มีนาคม 2021 Google ได้เปิดตัว Flutter 2 ระหว่างกิจกรรม Flutter Engage
|
||||
ออนไลน์ ได้เพิ่มตัวเรนเดอร์ที่ใช้ Canvas สำหรับเว็บ นอกเหนือจากตัวเรนเดอร์ที่ใช้ HTML
|
||||
และการสนับสนุนแอปพลิเคชันเดสก์ท็อปแบบทดลองสำหรับ Windows, macOS, และ Linux
|
||||
นอกจากนี้ยังมาพร้อมกับ Dart 2.0 ซึ่งรวมถึงการสนับสนุนด้านความปลอดภัยแบบ null (null-safety)
|
||||
ความปลอดภัยแบบ null เป็นทางเลือกในตอนแรกเนื่องจากเป็นการเปลี่ยนแปลงครั้งใหญ่และบังคับใช้ใน
|
||||
Dart 3 ที่เปิดตัวในปี 2023
|
||||
|
||||
# Linux build dependencies:
|
||||
sudo pacman -S --needed clang cmake ninja pkgconf gtk3
|
||||
#iii ในวันที่ 12 พฤษภาคม 2022 Flutter 3 และ Dart 2.17
|
||||
ได้รับการเผยแพร่โดยมีการรองรับแพลตฟอร์มเดสก์ท็อปทั้งหมดอย่างเสถียร
|
||||
|
||||
# Runtime dependencies:
|
||||
sudo pacman -S --needed util-linux-libs xz gtk3
|
||||
```
|
||||
#iii เมื่อวันที่ 27 ตุลาคม 2024 นักพัฒนาชุมชน Flutter จำนวนหนึ่งได้ประกาศเปิดตัว Flock
|
||||
ซึ่งเป็นเวอร์ชันแยกของ Flutter ที่มีจุดประสงค์เพื่อให้ง่ายต่อการร่วมพัฒนา
|
||||
ในขณะเดียวกันก็ยังคงรักษาความสอดคล้องกับทุกการเปลี่ยนแปลงที่เกิดขึ้นในโค้ดต้นทาง
|
||||
|
||||
=== macOS/iOS
|
||||
|
||||
#i การพัฒนาแอพลิเคชันสำหรับ macOS และ iOS นั้นต้องทำบน macOS เท่านั้นและจำเป็นต้องพึ่งพาเครื่องมือ Xcode แต่เนื่องจากในโครงงานนี้ไม่มีผู้ใช้ macOS จึงไม่สามารถสร้างไบนารีสำหรับ macOS และ iOS ออกมาได้ และไม่ใช่เป้าหมายของโครงงานนี้เช่นกัน
|
||||
#iii ในปี 2025 Google ยังคงพัฒนา Flutter ต่อไปด้วยสถาปัตยกรรมแบบโมดูลาร์ที่ได้รับการปรับปรุง
|
||||
การรองรับอุปกรณ์พับได้ และการเพิ่มประสิทธิภาพ ARM IoT ตามที่ระบุไว้ในแผนงานฉบับปรับปรุง
|
||||
|
||||
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 106 KiB |
|
After Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 63 KiB |
@@ -2,14 +2,14 @@
|
||||
|
||||
= Git
|
||||
|
||||
#i Git เป็นระบบซอฟต์แวร์ควบคุมเวอร์ชันแบบกระจาย ที่สามารถจัดการเวอร์ชันของซอร์สโคดหรือข้อมูลได้ มักใช้เพื่อควบคุมซอร์สโคดโดยโปรแกรมเมอร์ที่พัฒนาซอฟต์แวร์ร่วมกัน
|
||||
#h(1.7em) Git เป็นระบบซอฟต์แวร์ควบคุมเวอร์ชันแบบกระจาย ที่สามารถจัดการเวอร์ชันของซอร์สโคดหรือข้อมูลได้
|
||||
มักใช้เพื่อควบคุมซอร์สโคดโดยโปรแกรมเมอร์ที่พัฒนาซอฟต์แวร์ร่วมกัน
|
||||
|
||||
== Gitea
|
||||
|
||||
#i Gitea เป็นชุดซอฟต์แวร์ forge สำหรับการโฮสต์ระบบควบคุมเวอร์ชันการพัฒนาซอฟต์แวร์โดยใช้ Git รวมถึงฟีเจอร์การทำงานร่วมกันอื่น ๆ เช่น การติดตามบั๊ก การตรวจสอบโคด การผสานรวมอย่างต่อเนื่อง (Continuous Integration; CI) กระดาน Kanban ระบบรายงานปัญหา และวิกิ รองรับการโฮสต์ด้วยตนเอง และยังมีอินสแตนซ์สาธารณะของบุคคลที่หนึ่งให้ใช้งานฟรีอีกด้วย Gitea เป็นส่วนหนึ่งของ Gogs และเขียนด้วยภาษา Go Gitea สามารถโฮสต์ได้บนทุกแพลตฟอร์มที่รองรับ Go รวมถึง FreeBSD, Linux, macOS และ Windows โครงการนี้ได้รับทุนสนับสนุนจาก Open Collective
|
||||
|
||||
#i โครงงานนี้ใช้ Gitea (self-hosted) ในการโฮสต์โคดของโครงงาน โดยมี repository หลัก ๆ ดังนี้
|
||||
|
||||
- https://gitskette.dailitation.xyz/linesofcodes/liteauth-firmware32 - เฟิร์มแวร์ ESP32
|
||||
- https://gitskette.dailitation.xyz/linesofcodes/liteauthconfig - แอพลิเคชัน Flutter ตั้งค่าอุปกรณ์
|
||||
- https://gitskette.dailitation.xyz/linesofcodes/liteauthdocs - เอกสารโครงงานเล่มนี้
|
||||
#iii Gitea เป็นชุดซอฟต์แวร์ forge สำหรับการโฮสต์ระบบควบคุมเวอร์ชันการพัฒนาซอฟต์แวร์โดยใช้ Git
|
||||
รวมถึงฟีเจอร์การทำงานร่วมกันอื่น ๆ เช่น การติดตามบั๊ก การตรวจสอบโคด การผสานรวมอย่างต่อเนื่อง
|
||||
(Continuous Integration; CI) กระดาน Kanban ระบบรายงานปัญหา และวิกิ
|
||||
รองรับการโฮสต์ด้วยตนเอง และยังมีอินสแตนซ์สาธารณะของบุคคลที่หนึ่งให้ใช้งานฟรีอีกด้วย Gitea
|
||||
เป็นส่วนหนึ่งของ Gogs และเขียนด้วยภาษา Go Gitea สามารถโฮสต์ได้บนทุกแพลตฟอร์มที่รองรับ Go
|
||||
รวมถึง FreeBSD, Linux, macOS และ Windows โครงการนี้ได้รับทุนสนับสนุนจาก Open Collective
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
|
||||
= เกณฑ์วิธีขนส่งข้อความหลายมิติ (HyperText Transfer Protocol; HTTP)
|
||||
|
||||
#i HTTP (Hypertext Transfer Protocol) เป็น โปรโตคอลชั้นแอปพลิเคชันในชุดโปรโตคอลอินเทอร์เน็ตสำหรับระบบข้อมูลไฮเปอร์มีเดียแบบกระจายและร่วมมือกัน HTTP เป็นรากฐานของการสื่อสารข้อมูลสำหรับ World Wide Web ซึ่งเอกสารไฮเปอร์เท็กซ์ รวมถึง ไฮเปอร์ลิงก์ไปยังทรัพยากรอื่น ๆ ที่ผู้ใช้สามารถเข้าถึงได้อย่างง่ายดาย เช่น โดยการคลิกเมาส์ หรือโดยการแตะหน้าจอในเว็บเบราว์เซอร์
|
||||
#h(1.7em) HTTP (Hypertext Transfer Protocol) เป็น โปรโตคอลชั้นแอปพลิเคชันในชุดโปรโตคอลอินเทอร์เน็ตสำหรับระบบข้อมูลไฮเปอร์มีเดียแบบกระจายและร่วมมือกัน HTTP เป็นรากฐานของการสื่อสารข้อมูลสำหรับ World Wide Web ซึ่งเอกสารไฮเปอร์เท็กซ์ รวมถึง ไฮเปอร์ลิงก์ไปยังทรัพยากรอื่น ๆ ที่ผู้ใช้สามารถเข้าถึงได้อย่างง่ายดาย เช่น โดยการคลิกเมาส์ หรือโดยการแตะหน้าจอในเว็บเบราว์เซอร์
|
||||
|
||||
#i HTTP เป็น โปรโตคอลแบบคำขอ-การตอบกลับในโมเดลไคลเอนต์-เซิร์ฟเวอร์ ธุรกรรมเริ่มต้นเมื่อไคลเอนต์ส่งคำขอไปยังเซิร์ฟเวอร์ เซิร์ฟเวอร์จะพยายามตอบสนองคำขอและส่งการตอบกลับกลับไปยังไคลเอนต์ ซึ่งอธิบายการจัดการคำขอ และอาจมีทรัพยากรที่ร้องขอ เช่น เอกสาร HTML หรือเนื้อหาอื่น ๆ ก็ได้
|
||||
#h(1.7em) HTTP เป็น โปรโตคอลแบบคำขอ-การตอบกลับในโมเดลไคลเอนต์-เซิร์ฟเวอร์ ธุรกรรมเริ่มต้นเมื่อไคลเอนต์ส่งคำขอไปยังเซิร์ฟเวอร์ เซิร์ฟเวอร์จะพยายามตอบสนองคำขอและส่งการตอบกลับกลับไปยังไคลเอนต์ ซึ่งอธิบายการจัดการคำขอ และอาจมีทรัพยากรที่ร้องขอ เช่น เอกสาร HTML หรือเนื้อหาอื่น ๆ ก็ได้
|
||||
|
||||
#i ในสถานการณ์ทั่วไปเว็บเบราว์เซอร์ทำหน้าที่เป็นไคลเอนต์และเว็บเซิร์ฟเวอร์ที่โฮสต์เว็บไซต์หนึ่งเว็บไซต์หรือมากกว่านั้นคือ เซิร์ฟเวอร์ เว็บเบราว์เซอร์เป็นตัวอย่างของตัวแทนผู้ใช้ (UA) ตัวแทนผู้ใช้ประเภทอื่น ๆ ได้แก่ ซอฟต์แวร์จัดทำดัชนีที่ใช้โดยผู้ให้บริการค้นหา (เว็บครอว์เลอร์) เบราว์เซอร์เสียง แอปพลิเคชันมือถือ และซอฟต์แวร์อื่น ๆ ที่เข้าถึง ใช้ หรือแสดงเนื้อหาเว็บ
|
||||
#h(1.7em) ในสถานการณ์ทั่วไปเว็บเบราว์เซอร์ทำหน้าที่เป็นไคลเอนต์และเว็บเซิร์ฟเวอร์ที่โฮสต์เว็บไซต์หนึ่งเว็บไซต์หรือมากกว่านั้นคือ เซิร์ฟเวอร์ เว็บเบราว์เซอร์เป็นตัวอย่างของตัวแทนผู้ใช้ (UA) ตัวแทนผู้ใช้ประเภทอื่น ๆ ได้แก่ ซอฟต์แวร์จัดทำดัชนีที่ใช้โดยผู้ให้บริการค้นหา (เว็บครอว์เลอร์) เบราว์เซอร์เสียง แอปพลิเคชันมือถือ และซอฟต์แวร์อื่น ๆ ที่เข้าถึง ใช้ หรือแสดงเนื้อหาเว็บ
|
||||
|
||||
#i HTTP ถูกออกแบบมาเพื่ออนุญาตให้องค์ประกอบเครือข่ายตัวกลางสามารถปรับปรุงหรือเปิดใช้งานการสื่อสารระหว่างไคลเอนต์และเซิร์ฟเวอร์ เว็บไซต์ที่มีปริมาณการใช้งานสูงมักได้รับประโยชน์จาก เซิร์ฟเวอร์ แคชเว็บที่ส่งเนื้อหาแทนเซิร์ฟเวอร์ต้นทางเพื่อปรับปรุงเวลาตอบสนอง เว็บเบราว์เซอร์จะแคชทรัพยากรเว็บที่เข้าถึงก่อนหน้านี้และนำกลับมาใช้ซ้ำทุกครั้งที่ทำได้เพื่อลดปริมาณการใช้งานเครือข่ายพร็อกซีเซิร์ฟเวอร์ HTTP ที่ ขอบเขต เครือข่ายส่วนตัวสามารถอำนวยความสะดวกในการสื่อสารสำหรับไคลเอนต์ที่ไม่มีที่อยู่ที่กำหนดเส้นทางได้ทั่วโลก โดยการส่งต่อข้อความไปยังเซิร์ฟเวอร์ภายนอก
|
||||
#h(1.7em) HTTP ถูกออกแบบมาเพื่ออนุญาตให้องค์ประกอบเครือข่ายตัวกลางสามารถปรับปรุงหรือเปิดใช้งานการสื่อสารระหว่างไคลเอนต์และเซิร์ฟเวอร์ เว็บไซต์ที่มีปริมาณการใช้งานสูงมักได้รับประโยชน์จาก เซิร์ฟเวอร์ แคชเว็บที่ส่งเนื้อหาแทนเซิร์ฟเวอร์ต้นทางเพื่อปรับปรุงเวลาตอบสนอง เว็บเบราว์เซอร์จะแคชทรัพยากรเว็บที่เข้าถึงก่อนหน้านี้และนำกลับมาใช้ซ้ำทุกครั้งที่ทำได้เพื่อลดปริมาณการใช้งานเครือข่ายพร็อกซีเซิร์ฟเวอร์ HTTP ที่ ขอบเขต เครือข่ายส่วนตัวสามารถอำนวยความสะดวกในการสื่อสารสำหรับไคลเอนต์ที่ไม่มีที่อยู่ที่กำหนดเส้นทางได้ทั่วโลก โดยการส่งต่อข้อความไปยังเซิร์ฟเวอร์ภายนอก
|
||||
|
||||
#i เพื่ออนุญาตให้โหนด HTTP ตัวกลาง (พร็อกซีเซิร์ฟเวอร์ แคชเว็บ ฯลฯ) ทำหน้าที่ของตนได้ ส่วนหัว HTTP บางส่วน (พบในคำขอ/การตอบสนอง HTTP) จะได้รับการจัดการแบบฮอปต่อฮอปในขณะที่ส่วนหัว HTTP อื่นๆ จะได้รับการจัดการแบบต้นทางถึงปลายทาง (จัดการโดยไคลเอนต์ต้นทางและเว็บเซิร์ฟเวอร์เป้าหมายเท่านั้น)
|
||||
#h(1.7em) เพื่ออนุญาตให้โหนด HTTP ตัวกลาง (พร็อกซีเซิร์ฟเวอร์ แคชเว็บ ฯลฯ) ทำหน้าที่ของตนได้ ส่วนหัว HTTP บางส่วน (พบในคำขอ/การตอบสนอง HTTP) จะได้รับการจัดการแบบฮอปต่อฮอปในขณะที่ส่วนหัว HTTP อื่นๆ จะได้รับการจัดการแบบต้นทางถึงปลายทาง (จัดการโดยไคลเอนต์ต้นทางและเว็บเซิร์ฟเวอร์เป้าหมายเท่านั้น)
|
||||
|
||||
#i ทรัพยากรบนเว็บจะถูกระบุตำแหน่งโดยตัวระบุทรัพยากรแบบสากล (URL) โดยใช้รูปแบบ Uniform Resource Identifier (URI) _http_ และ _https_ โดย URI จะถูกเข้ารหัสเป็นไฮเปอร์ลิงก์ในเอกสาร HTML เพื่อสร้างเอกสารไฮเปอร์เท็กซ์ที่เชื่อมโยงกัน
|
||||
#h(1.7em) ทรัพยากรบนเว็บจะถูกระบุตำแหน่งโดยตัวระบุทรัพยากรแบบสากล (URL) โดยใช้รูปแบบ Uniform Resource Identifier (URI) _http_ และ _https_ โดย URI จะถูกเข้ารหัสเป็นไฮเปอร์ลิงก์ในเอกสาร HTML เพื่อสร้างเอกสารไฮเปอร์เท็กซ์ที่เชื่อมโยงกัน
|
||||
|
||||
@@ -2,87 +2,244 @@
|
||||
|
||||
= เกณฑ์วิธีขนส่งข้อความหลายมิติแบบมั่นคง (Hypertext Transfer Protocol Secure; HTTPS)
|
||||
|
||||
#i เกณฑ์วิธีขนส่งข้อความหลายมิติแบบมั่นคง (Hypertext Transfer Protocol Secure; HTTPS) คือส่วนต่อขยายของโปรโตคอลเกณฑ์วิธีขนส่งข้อความหลายมิติ (Hypertext Transfer Protocol; HTTP) ซึ่งใช้การเข้ารหัสเพื่อการสื่อสารที่ปลอดภัยผ่านเครือข่ายคอมพิวเตอร์ และถูกใช้อย่างแพร่หลายบนอินเทอร์เน็ต โดยโปรโตคอลเครือข่าย HTTPS จะถูกเข้ารหัสด้วยเกณฑ์วิธีความมั่นคงของชั้นขนส่ง (Transport Layer Security; TLS) หรือก่อนหน้านี้คือเกณฑ์วิธีชั้นซ็อกเก็ตปลอดภัย (Secure Sockets Layer; SSL) ด้วยเหตุนั้น โปรโตคอลนี้สามารถเรียกด้วยชื่อ HTTP over TLS หรือ HTTP over SSL ได้เช่นกัน
|
||||
#h(1.7em) เกณฑ์วิธีขนส่งข้อความหลายมิติแบบมั่นคง (Hypertext Transfer Protocol Secure;
|
||||
HTTPS) คือส่วนต่อขยายของโปรโตคอลเกณฑ์วิธีขนส่งข้อความหลายมิติ (Hypertext Transfer
|
||||
Protocol; HTTP) ซึ่งใช้การเข้ารหัสเพื่อการสื่อสารที่ปลอดภัยผ่านเครือข่ายคอมพิวเตอร์
|
||||
และถูกใช้อย่างแพร่หลายบนอินเทอร์เน็ต โดยโปรโตคอลเครือข่าย HTTPS
|
||||
จะถูกเข้ารหัสด้วยเกณฑ์วิธีความมั่นคงของชั้นขนส่ง (Transport Layer Security; TLS)
|
||||
หรือก่อนหน้านี้คือเกณฑ์วิธีชั้นซ็อกเก็ตปลอดภัย (Secure Sockets Layer; SSL) ด้วยเหตุนั้น
|
||||
โปรโตคอลนี้สามารถเรียกด้วยชื่อ HTTP over TLS หรือ HTTP over SSL ได้เช่นกัน
|
||||
|
||||
#i แรงจูงใจหลักของ HTTPS คือการยืนยันตัวตนของเว็บไซต์ที่เข้าถึง และการปกป้องความเป็นส่วนตัวและความสมบูรณ์ของข้อมูลที่แลกเปลี่ยนระหว่างการรับส่งข้อมูล HTTPS ป้องกันการโจมตีแบบ man-in-the-middle และการเข้ารหัสบล็อกไซเฟอร์แบบสองทิศทางในการสื่อสารระหว่างไคลเอนต์และเซิร์ฟเวอร์ ช่วยป้องกันการสื่อสารจากการดักฟังและการปลอมแปลง ประเด็นการพิสูจน์ตัวตนของ HTTPS จำเป็นต้องมีบุคคลที่สามที่เชื่อถือได้ลงนามในใบรับรองดิจิทัลฝั่งเซิร์ฟเวอร์ เดิมทีการดำเนินการนี้มีค่าใช้จ่ายสูง ซึ่งหมายความว่าการเชื่อมต่อ HTTPS ที่ผ่านการรับรองความถูกต้องอย่างสมบูรณ์มักจะพบได้เฉพาะในบริการธุรกรรมการชำระเงินที่ปลอดภัยและระบบสารสนเทศขององค์กรที่ปลอดภัยอื่นๆ บนเวิลด์ไวด์เว็บเท่านั้น ในปี 2016 แคมเปญโดยมูลนิธิพรมแดนอิเล็กทรอนิกส์ (Electronic Frontier Foundation; EFF) ด้วยการสนับสนุนจากนักพัฒนาเว็บเบราว์เซอร์ ทำให้โปรโตคอลนี้แพร่หลายมากขึ้น นับตั้งแต่ปี 2018 เป็นต้นมา HTTPS ถูกใช้โดยผู้ใช้เว็บบ่อยกว่า HTTP ดั้งเดิมที่ไม่ปลอดภัย โดยส่วนใหญ่เพื่อปกป้องความถูกต้องของหน้าเว็บบนเว็บไซต์ทุกประเภท รักษาความปลอดภัยบัญชี และรักษาความเป็นส่วนตัวของการสื่อสาร การระบุตัวตน และการท่องเว็บของผู้ใช้
|
||||
#h(1.7em) แรงจูงใจหลักของ HTTPS คือการยืนยันตัวตนของเว็บไซต์ที่เข้าถึง
|
||||
และการปกป้องความเป็นส่วนตัวและความสมบูรณ์ของข้อมูลที่แลกเปลี่ยนระหว่างการรับส่งข้อมูล HTTPS
|
||||
ป้องกันการโจมตีแบบ man-in-the-middle
|
||||
และการเข้ารหัสบล็อกไซเฟอร์แบบสองทิศทางในการสื่อสารระหว่างไคลเอนต์และเซิร์ฟเวอร์
|
||||
ช่วยป้องกันการสื่อสารจากการดักฟังและการปลอมแปลง ประเด็นการพิสูจน์ตัวตนของ HTTPS
|
||||
จำเป็นต้องมีบุคคลที่สามที่เชื่อถือได้ลงนามในใบรับรองดิจิทัลฝั่งเซิร์ฟเวอร์ เดิมทีการดำเนินการนี้มีค่าใช้จ่ายสูง
|
||||
ซึ่งหมายความว่าการเชื่อมต่อ HTTPS
|
||||
ที่ผ่านการรับรองความถูกต้องอย่างสมบูรณ์มักจะพบได้เฉพาะในบริการธุรกรรมการชำระเงินที่ปลอดภัยและระบบสารสนเทศขององค์กรที่ปลอดภัยอื่นๆ
|
||||
บนเวิลด์ไวด์เว็บเท่านั้น ในปี 2016 แคมเปญโดยมูลนิธิพรมแดนอิเล็กทรอนิกส์ (Electronic Frontier
|
||||
Foundation; EFF) ด้วยการสนับสนุนจากนักพัฒนาเว็บเบราว์เซอร์ ทำให้โปรโตคอลนี้แพร่หลายมากขึ้น
|
||||
นับตั้งแต่ปี 2018 เป็นต้นมา HTTPS ถูกใช้โดยผู้ใช้เว็บบ่อยกว่า HTTP ดั้งเดิมที่ไม่ปลอดภัย
|
||||
โดยส่วนใหญ่เพื่อปกป้องความถูกต้องของหน้าเว็บบนเว็บไซต์ทุกประเภท รักษาความปลอดภัยบัญชี
|
||||
และรักษาความเป็นส่วนตัวของการสื่อสาร การระบุตัวตน และการท่องเว็บของผู้ใช้
|
||||
|
||||
== โดยรวม
|
||||
|
||||
#i รูปแบบ Uniform Resource Identifier (URI) ของ HTTPS มีรูปแบบการใช้งานที่เหมือนกันกับรูปแบบ HTTP อย่างไรก็ตาม HTTPS จะส่งสัญญาณให้เบราว์เซอร์ใช้ชั้นการเข้ารหัสเพิ่มเติมของ SSL/TLS เพื่อปกป้องการรับส่งข้อมูลซึ่ง SSL/TLS เหมาะอย่างยิ่งสำหรับ HTTP เนื่องจากสามารถให้การป้องกันได้แม้ว่าจะมีการตรวจสอบความถูกต้องเพียงด้านเดียวของการสื่อสาร ในกรณีนี้คือธุรกรรม HTTP บนอินเทอร์เน็ต ซึ่งโดยทั่วไปมีเพียงเซิร์ฟเวอร์เท่านั้นที่ได้รับการรับรองความถูกต้อง (โดยไคลเอนต์ตรวจสอบใบรับรองของเซิร์ฟเวอร์)
|
||||
#iii รูปแบบ Uniform Resource Identifier (URI) ของ HTTPS
|
||||
มีรูปแบบการใช้งานที่เหมือนกันกับรูปแบบ HTTP อย่างไรก็ตาม HTTPS
|
||||
จะส่งสัญญาณให้เบราว์เซอร์ใช้ชั้นการเข้ารหัสเพิ่มเติมของ SSL/TLS เพื่อปกป้องการรับส่งข้อมูลซึ่ง SSL/TLS
|
||||
เหมาะอย่างยิ่งสำหรับ HTTP
|
||||
เนื่องจากสามารถให้การป้องกันได้แม้ว่าจะมีการตรวจสอบความถูกต้องเพียงด้านเดียวของการสื่อสาร
|
||||
ในกรณีนี้คือธุรกรรม HTTP บนอินเทอร์เน็ต
|
||||
ซึ่งโดยทั่วไปมีเพียงเซิร์ฟเวอร์เท่านั้นที่ได้รับการรับรองความถูกต้อง
|
||||
(โดยไคลเอนต์ตรวจสอบใบรับรองของเซิร์ฟเวอร์)
|
||||
|
||||
#i HTTPS สร้างช่องทางที่ปลอดภัยบนเครือข่ายที่ไม่ปลอดภัย วิธีนี้ช่วยให้มั่นใจได้ถึงการป้องกันที่เหมาะสมจากผู้ดักฟังและการโจมตีแบบ man-in-the-middle โดยมีเงื่อนไขว่ามีการใช้ชุดการเข้ารหัสที่เหมาะสม และใบรับรองเซิร์ฟเวอร์ได้รับการตรวจสอบและเชื่อถือได้
|
||||
#iii HTTPS สร้างช่องทางที่ปลอดภัยบนเครือข่ายที่ไม่ปลอดภัย
|
||||
วิธีนี้ช่วยให้มั่นใจได้ถึงการป้องกันที่เหมาะสมจากผู้ดักฟังและการโจมตีแบบ man-in-the-middle
|
||||
โดยมีเงื่อนไขว่ามีการใช้ชุดการเข้ารหัสที่เหมาะสม และใบรับรองเซิร์ฟเวอร์ได้รับการตรวจสอบและเชื่อถือได้
|
||||
|
||||
#i เนื่องจาก HTTPS เชื่อมโยง HTTP ทั้งหมดเข้ากับ TLS โดยตรงจึงสามารถเข้ารหัสโปรโตคอล HTTP พื้นฐานทั้งหมดได้ ซึ่งรวมถึง URL ของคำขอ พารามิเตอร์การค้นหา ส่วนหัว และคุกกี้ (ซึ่งมักจะมีข้อมูลระบุตัวตนของผู้ใช้) อย่างไรก็ตาม เนื่องจากที่อยู่เว็บไซต์และหมายเลขพอร์ตเป็นส่วนหนึ่งของโปรโตคอล TCP/IP พื้นฐาน HTTPS จึงไม่สามารถปกป้องการเปิดเผยข้อมูลเหล่านี้ได้ ในทางปฏิบัติ หมายความว่าแม้แต่บนเว็บเซิร์ฟเวอร์ที่กำหนดค่าอย่างถูกต้อง ผู้ดักฟังก็สามารถอนุมานที่อยู่ IP และหมายเลขพอร์ตของเว็บเซิร์ฟเวอร์ และบางครั้งอาจรวมถึงชื่อโดเมน (เช่น www.example.org แต่ไม่สามารถอนุมานส่วนที่เหลือของ URL) ที่ผู้ใช้กำลังสื่อสารด้วย รวมถึงปริมาณข้อมูลที่ถ่ายโอนและระยะเวลาของการสื่อสาร แต่อย่างไรก็ตามไม่รวมถึงเนื้อหาของการสื่อสาร
|
||||
#iii เนื่องจาก HTTPS เชื่อมโยง HTTP ทั้งหมดเข้ากับ TLS โดยตรงจึงสามารถเข้ารหัสโปรโตคอล HTTP
|
||||
พื้นฐานทั้งหมดได้ ซึ่งรวมถึง URL ของคำขอ พารามิเตอร์การค้นหา ส่วนหัว และคุกกี้
|
||||
(ซึ่งมักจะมีข้อมูลระบุตัวตนของผู้ใช้) อย่างไรก็ตาม
|
||||
เนื่องจากที่อยู่เว็บไซต์และหมายเลขพอร์ตเป็นส่วนหนึ่งของโปรโตคอล TCP/IP พื้นฐาน HTTPS
|
||||
จึงไม่สามารถปกป้องการเปิดเผยข้อมูลเหล่านี้ได้ ในทางปฏิบัติ
|
||||
หมายความว่าแม้แต่บนเว็บเซิร์ฟเวอร์ที่กำหนดค่าอย่างถูกต้อง ผู้ดักฟังก็สามารถอนุมานที่อยู่ IP
|
||||
และหมายเลขพอร์ตของเว็บเซิร์ฟเวอร์ และบางครั้งอาจรวมถึงชื่อโดเมน (เช่น www.example.org
|
||||
แต่ไม่สามารถอนุมานส่วนที่เหลือของ URL) ที่ผู้ใช้กำลังสื่อสารด้วย
|
||||
รวมถึงปริมาณข้อมูลที่ถ่ายโอนและระยะเวลาของการสื่อสาร แต่อย่างไรก็ตามไม่รวมถึงเนื้อหาของการสื่อสาร
|
||||
|
||||
#i เว็บเบราว์เซอร์รู้วิธีเชื่อถือเว็บไซต์ HTTPS โดยอ้างอิงจากผู้ให้บริการออกใบรับรอง (Certificate Authority) ที่ติดตั้งไว้ล่วงหน้าในซอฟต์แวร์ ผู้สร้างเว็บเบราว์เซอร์จึงไว้วางใจผู้ให้บริการออกใบรับรองในการออกใบรับรองที่ถูกต้อง ดังนั้น ผู้ใช้ควรเชื่อถือการเชื่อมต่อ HTTPS ไปยังเว็บไซต์ก็ต่อเมื่อเป็นไปตามเงื่อนไขทั้งหมดต่อไปนี้:
|
||||
#iii เว็บเบราว์เซอร์รู้วิธีเชื่อถือเว็บไซต์ HTTPS โดยอ้างอิงจากผู้ให้บริการออกใบรับรอง#jb
|
||||
(Certificate Authority) ที่ติดตั้งไว้ล่วงหน้าในซอฟต์แวร์
|
||||
ผู้สร้างเว็บเบราว์เซอร์จึงไว้วางใจผู้ให้บริการออกใบรับรองในการออกใบรับรองที่ถูกต้อง ดังนั้น
|
||||
ผู้ใช้ควรเชื่อถือการเชื่อมต่อ HTTPS ไปยังเว็บไซต์ก็ต่อเมื่อเป็นไปตามเงื่อนไขทั้งหมดต่อไปนี้:
|
||||
|
||||
- ผู้ใช้เชื่อมั่นว่าอุปกรณ์ของตน โฮสต์เบราว์เซอร์ และวิธีการเข้าถึงเบราว์เซอร์นั้นไม่ถูกบุกรุก (กล่าวคือ ไม่มีการโจมตีซัพพลายเชน)
|
||||
- ผู้ใช้เชื่อมั่นว่าซอฟต์แวร์เบราว์เซอร์ใช้งาน HTTPS ได้อย่างถูกต้องพร้อมกับผู้ให้บริการออกใบรับรองที่ติดตั้งไว้ล่วงหน้าอย่างถูกต้อง
|
||||
- ผู้ใช้เชื่อมั่นว่าผู้ให้บริการออกใบรับรองจะรับรองเฉพาะเว็บไซต์ที่ถูกต้องตามกฎหมายเท่านั้น (กล่าวคือ ผู้ให้บริการออกใบรับรองจะไม่ถูกบุกรุกและไม่มีการออกใบรับรองที่ผิดพลาด)
|
||||
- เว็บไซต์มีใบรับรองที่ถูกต้อง ซึ่งหมายความว่าได้รับการลงนามโดยผู้ให้บริการที่เชื่อถือได้
|
||||
- ใบรับรองระบุเว็บไซต์ได้อย่างถูกต้อง (เช่น เมื่อเบราว์เซอร์เข้าชม https://example.com ใบรับรองที่ได้รับนั้นถูกต้องสำหรับ example.com และไม่ใช่ของหน่วยงานอื่น)
|
||||
- ผู้ใช้เชื่อมั่นว่าเลเยอร์การเข้ารหัสของโปรโตคอล (SSL/TLS) มีความปลอดภัยเพียงพอจากการดักฟัง
|
||||
#[
|
||||
#set enum(indent: 6em)
|
||||
1. ผู้ใช้เชื่อมั่นว่าอุปกรณ์ของตน โฮสต์เบราว์เซอร์ และวิธีการเข้าถึงเบราว์เซอร์นั้นไม่ถูกบุกรุก (กล่าวคือ
|
||||
ไม่มีการโจมตีซัพพลายเชน)
|
||||
2. ผู้ใช้เชื่อมั่นว่าซอฟต์แวร์เบราว์เซอร์ใช้งาน HTTPS
|
||||
ได้อย่างถูกต้องพร้อมกับผู้ให้บริการออกใบรับรองที่ติดตั้งไว้ล่วงหน้าอย่างถูกต้อง
|
||||
3. ผู้ใช้เชื่อมั่นว่าผู้ให้บริการออกใบรับรองจะรับรองเฉพาะเว็บไซต์ที่ถูกต้องตามกฎหมายเท่านั้น (กล่าวคือ
|
||||
ผู้ให้บริการออกใบรับรองจะไม่ถูกบุกรุกและไม่มีการออกใบรับรองที่ผิดพลาด)
|
||||
4. เว็บไซต์มีใบรับรองที่ถูกต้อง ซึ่งหมายความว่าได้รับการลงนามโดยผู้ให้บริการที่เชื่อถือได้
|
||||
5. ใบรับรองระบุเว็บไซต์ได้อย่างถูกต้อง (เช่น เมื่อเบราว์เซอร์เข้าชม https://example.com
|
||||
ใบรับรองที่ได้รับนั้นถูกต้องสำหรับ example.com และไม่ใช่ของหน่วยงานอื่น)
|
||||
6. ผู้ใช้เชื่อมั่นว่าเลเยอร์การเข้ารหัสของโปรโตคอล (SSL/TLS) มีความปลอดภัยเพียงพอจากการดักฟัง
|
||||
]
|
||||
|
||||
#i HTTPS มีความสำคัญอย่างยิ่งต่อเครือข่ายที่ไม่ปลอดภัยและเครือข่ายที่อาจถูกแทรกแซง เครือข่ายที่ไม่ปลอดภัย เช่น จุดเชื่อมต่อ Wi-Fi สาธารณะ ซึ่งเปิดโอกาสให้ทุกคนในเครือข่ายท้องถิ่นเดียวกันสามารถดักจับแพ็กเก็ตและค้นพบข้อมูลสำคัญที่ไม่ได้รับการป้องกันโดย HTTPS นอกจากนี้ ยังพบว่าเครือข่าย WLAN ทั้งแบบฟรีและแบบเสียเงินบางเครือข่ายได้แทรกแซงหน้าเว็บโดยการแทรกแพ็กเก็ตเพื่อแสดงโฆษณาของตนเองบนเว็บไซต์อื่น การกระทำเช่นนี้สามารถถูกนำไปใช้ในทางที่ผิดได้หลายวิธี เช่น การฉีดมัลแวร์ลงในหน้าเว็บและการขโมยข้อมูลส่วนบุคคลของผู้ใช้
|
||||
#iii HTTPS มีความสำคัญอย่างยิ่งต่อเครือข่ายที่ไม่ปลอดภัยและเครือข่ายที่อาจถูกแทรกแซง
|
||||
เครือข่ายที่ไม่ปลอดภัย เช่น จุดเชื่อมต่อ Wi-Fi สาธารณะ
|
||||
ซึ่งเปิดโอกาสให้ทุกคนในเครือข่ายท้องถิ่นเดียวกันสามารถดักจับแพ็กเก็ตและค้นพบข้อมูลสำคัญที่ไม่ได้รับการป้องกันโดย
|
||||
HTTPS นอกจากนี้ ยังพบว่าเครือข่าย WLAN
|
||||
ทั้งแบบฟรีและแบบเสียเงินบางเครือข่ายได้แทรกแซงหน้าเว็บโดยการแทรกแพ็กเก็ตเพื่อแสดงโฆษณาของตนเองบนเว็บไซต์อื่น
|
||||
การกระทำเช่นนี้สามารถถูกนำไปใช้ในทางที่ผิดได้หลายวิธี เช่น
|
||||
การฉีดมัลแวร์ลงในหน้าเว็บและการขโมยข้อมูลส่วนบุคคลของผู้ใช้
|
||||
|
||||
#i เมื่อมีข้อมูลมากขึ้นเกี่ยวกับการเฝ้าระวังมวลชนทั่วโลกและการขโมยข้อมูลส่วนบุคคลของอาชญากร การใช้ระบบรักษาความปลอดภัย HTTPS บนเว็บไซต์ทั้งหมดจึงมีความสำคัญเพิ่มมากขึ้นเรื่อยๆ โดยไม่คำนึงถึงประเภทของการเชื่อมต่ออินเทอร์เน็ตที่ใช้งาน แม้ว่าข้อมูลเมตาเกี่ยวกับหน้าเว็บแต่ละหน้าที่ผู้ใช้เข้าชมอาจไม่ถือว่ามีความละเอียดอ่อน แต่เมื่อนำมารวมกันแล้ว ข้อมูลเมตาเหล่านี้อาจเปิดเผยข้อมูลเกี่ยวกับผู้ใช้ได้มาก และกระทบต่อความเป็นส่วนตัวของผู้ใช้
|
||||
#iii เมื่อมีข้อมูลมากขึ้นเกี่ยวกับการเฝ้าระวังมวลชนทั่วโลกและการขโมยข้อมูลส่วนบุคคลของอาชญากร
|
||||
การใช้ระบบรักษาความปลอดภัย HTTPS บนเว็บไซต์ทั้งหมดจึงมีความสำคัญเพิ่มมากขึ้นเรื่อยๆ
|
||||
โดยไม่คำนึงถึงประเภทของการเชื่อมต่ออินเทอร์เน็ตที่ใช้งาน
|
||||
แม้ว่าข้อมูลเมตาเกี่ยวกับหน้าเว็บแต่ละหน้าที่ผู้ใช้เข้าชมอาจไม่ถือว่ามีความละเอียดอ่อน
|
||||
แต่เมื่อนำมารวมกันแล้ว ข้อมูลเมตาเหล่านี้อาจเปิดเผยข้อมูลเกี่ยวกับผู้ใช้ได้มาก
|
||||
และกระทบต่อความเป็นส่วนตัวของผู้ใช้
|
||||
|
||||
#i การปรับใช้ HTTPS ยังอนุญาตให้ใช้ HTTP/2 และ HTTP/3 (และรุ่นก่อนหน้าอย่าง SPDY และ QUIC) ซึ่งเป็น HTTP เวอร์ชันใหม่ที่ออกแบบมาเพื่อลดเวลา ขนาด และความหน่วงในการโหลดหน้าเว็บ
|
||||
|
||||
#i และมีการแนะนำให้ใช้ HTTP Strict Transport Security (HSTS) ร่วมกับ HTTPS เพื่อป้องกันผู้ใช้จากการโจมตีแบบ man-in-the-middle โดยเฉพาะอย่างยิ่ง SSL stripping
|
||||
#iii การปรับใช้ HTTPS ยังอนุญาตให้ใช้ HTTP/2 และ HTTP/3 (และรุ่นก่อนหน้าอย่าง SPDY และ
|
||||
QUIC) ซึ่งเป็น HTTP เวอร์ชันใหม่ที่ออกแบบมาเพื่อลดเวลา ขนาด และความหน่วงในการโหลดหน้าเว็บ
|
||||
และมีการแนะนำให้ใช้ HTTP Strict Transport Security (HSTS) ร่วมกับ HTTPS
|
||||
เพื่อป้องกันผู้ใช้จากการโจมตีแบบ man-in-the-middle โดยเฉพาะอย่างยิ่ง SSL stripping
|
||||
|
||||
== ความปลอดภัย
|
||||
|
||||
#i ความปลอดภัยของ HTTPS อยู่ที่ TLS พื้นฐาน ซึ่งโดยทั่วไปจะใช้คีย์สาธารณะและคีย์ส่วนตัวระยะยาวเพื่อสร้างคีย์เซสชันระยะสั้น ซึ่งจะถูกนำไปใช้ในการเข้ารหัสการไหลของข้อมูลระหว่างไคลเอนต์และเซิร์ฟเวอร์ ใบรับรอง X.509 ถูกใช้เพื่อยืนยันตัวตนของเซิร์ฟเวอร์ (และบางครั้งรวมถึงไคลเอนต์ด้วย) ด้วยเหตุนี้ ผู้ให้บริการออกใบรับรองและใบรับรองคีย์สาธารณะจึงจำเป็นต่อการตรวจสอบความสัมพันธ์ระหว่างใบรับรองและเจ้าของ รวมถึงการสร้าง ลงนาม และดูแลความถูกต้องของใบรับรอง แม้ว่าวิธีนี้อาจมีประโยชน์มากกว่าการตรวจสอบตัวตนผ่านเครือข่ายที่เชื่อถือได้ แต่การเปิดเผยข้อมูลการเฝ้าระวังข้อมูลจำนวนมากในปี 2013 ได้ชี้ให้เห็นถึงผู้ให้บริการออกใบรับรองว่าเป็นจุดอ่อนที่อาจนำไปสู่การโจมตีแบบ man-in-the-middle คุณสมบัติที่สำคัญในบริบทนี้คือความลับแบบส่งต่อ (Forward Secrecy) ซึ่งรับประกันว่าการสื่อสารที่เข้ารหัสที่บันทึกไว้ในอดีตจะไม่สามารถดึงข้อมูลและถอดรหัสได้ หากคีย์ลับหรือรหัสผ่านระยะยาวถูกบุกรุกในอนาคต ไม่ใช่ทุกเว็บเซิร์ฟเวอร์ที่จะมีระบบความลับแบบส่งต่อ
|
||||
#iii ความปลอดภัยของ HTTPS อยู่ที่ TLS พื้นฐาน
|
||||
ซึ่งโดยทั่วไปจะใช้คีย์สาธารณะและคีย์ส่วนตัวระยะยาวเพื่อสร้างคีย์เซสชันระยะสั้น
|
||||
ซึ่งจะถูกนำไปใช้ในการเข้ารหัสการไหลของข้อมูลระหว่างไคลเอนต์และเซิร์ฟเวอร์ ใบรับรอง X.509
|
||||
ถูกใช้เพื่อยืนยันตัวตนของเซิร์ฟเวอร์ (และบางครั้งรวมถึงไคลเอนต์ด้วย) ด้วยเหตุนี้
|
||||
ผู้ให้บริการออกใบรับรองและใบรับรองคีย์สาธารณะจึงจำเป็นต่อการตรวจสอบความสัมพันธ์ระหว่างใบรับรองและเจ้าของ
|
||||
รวมถึงการสร้าง ลงนาม และดูแลความถูกต้องของใบรับรอง
|
||||
แม้ว่าวิธีนี้อาจมีประโยชน์มากกว่าการตรวจสอบตัวตนผ่านเครือข่ายที่เชื่อถือได้
|
||||
แต่การเปิดเผยข้อมูลการเฝ้าระวังข้อมูลจำนวนมากในปี 2013
|
||||
ได้ชี้ให้เห็นถึงผู้ให้บริการออกใบรับรองว่าเป็นจุดอ่อนที่อาจนำไปสู่การโจมตีแบบ man-in-the-middle
|
||||
คุณสมบัติที่สำคัญในบริบทนี้คือความลับแบบส่งต่อ (Forward Secrecy)
|
||||
ซึ่งรับประกันว่าการสื่อสารที่เข้ารหัสที่บันทึกไว้ในอดีตจะไม่สามารถดึงข้อมูลและถอดรหัสได้
|
||||
หากคีย์ลับหรือรหัสผ่านระยะยาวถูกบุกรุกในอนาคต ไม่ใช่ทุกเว็บเซิร์ฟเวอร์ที่จะมีระบบความลับแบบส่งต่อ
|
||||
|
||||
#i เพื่อให้ HTTPS มีประสิทธิภาพ เว็บไซต์จะต้องโฮสต์ผ่าน HTTPS ทั้งหมด หากเนื้อหาบางส่วนของเว็บไซต์ถูกโหลดผ่าน HTTP (เช่น สคริปต์หรือรูปภาพ) หรือหากโหลดเฉพาะหน้าที่มีข้อมูลละเอียดอ่อน เช่น หน้าเข้าสู่ระบบ ผ่าน HTTPS ขณะที่ส่วนอื่นๆ ของเว็บไซต์ผ่าน HTTP ธรรมดา ผู้ใช้จะเสี่ยงต่อการถูกโจมตีและการเฝ้าระวัง นอกจากนี้ คุกกี้บนเว็บไซต์ที่รันผ่าน HTTPS จะต้องเปิดใช้งานแอตทริบิวต์ secure ในเว็บไซต์ที่มีข้อมูลละเอียดอ่อน ผู้ใช้และเซสชันจะถูกเปิดเผยทุกครั้งที่เข้าถึงเว็บไซต์นั้นด้วย HTTP แทนที่จะเป็น HTTPS
|
||||
#iii เพื่อให้ HTTPS มีประสิทธิภาพ เว็บไซต์จะต้องโฮสต์ผ่าน HTTPS ทั้งหมด
|
||||
หากเนื้อหาบางส่วนของเว็บไซต์ถูกโหลดผ่าน HTTP (เช่น สคริปต์หรือรูปภาพ)
|
||||
หรือหากโหลดเฉพาะหน้าที่มีข้อมูลละเอียดอ่อน เช่น หน้าเข้าสู่ระบบ ผ่าน HTTPS ขณะที่ส่วนอื่น ๆ
|
||||
ของเว็บไซต์ผ่าน HTTP ธรรมดา#jb ผู้ใช้จะเสี่ยงต่อการถูกโจมตีและการเฝ้าระวัง นอกจากนี้
|
||||
คุกกี้บนเว็บไซต์ที่รันผ่าน HTTPS จะต้องเปิดใช้งานแอตทริบิวต์ secure ในเว็บไซต์ที่มีข้อมูลละเอียดอ่อน
|
||||
ผู้ใช้และเซสชันจะถูกเปิดเผยทุกครั้งที่เข้าถึงเว็บไซต์นั้นด้วย HTTP แทนที่จะเป็น HTTPS
|
||||
|
||||
#pagebreak()
|
||||
|
||||
== รายละเอียดทางเทคนิค
|
||||
|
||||
=== ความแตกต่างจาก HTTP
|
||||
|
||||
#i URL แบบ HTTPS เริ่มต้นด้วย "https://" และใช้พอร์ต 443 ตามค่าเริ่มต้น ในขณะที่ URL แบบ HTTP เริ่มต้นด้วย "http://" และใช้พอร์ต 80 ตามค่าเริ่มต้น
|
||||
#iiii URL แบบ HTTPS เริ่มต้นด้วย "https://" และใช้พอร์ต 443 ตามค่าเริ่มต้น ในขณะที่ URL แบบ
|
||||
HTTP เริ่มต้นด้วย "http://" และใช้พอร์ต 80 ตามค่าเริ่มต้น
|
||||
|
||||
#i HTTP ไม่ได้เข้ารหัส จึงมีความเสี่ยงต่อการโจมตีแบบ man-in-the-middle และการดักฟังซึ่งอาจทำให้ผู้โจมตีสามารถเข้าถึงบัญชีเว็บไซต์และข้อมูลสำคัญ และแก้ไขหน้าเว็บเพื่อแทรกมัลแวร์หรือโฆษณาได้ HTTPS ได้รับการออกแบบมาให้ทนทานต่อการโจมตีประเภทนี้ และถือว่าปลอดภัย (ยกเว้นการใช้งาน HTTPS ที่ใช้ SSL เวอร์ชันที่ล้าสมัย)
|
||||
#iiii HTTP ไม่ได้เข้ารหัส จึงมีความเสี่ยงต่อการโจมตีแบบ man-in-the-middle
|
||||
และการดักฟังซึ่งอาจทำให้ผู้โจมตีสามารถเข้าถึงบัญชีเว็บไซต์และข้อมูลสำคัญ
|
||||
และแก้ไขหน้าเว็บเพื่อแทรกมัลแวร์หรือโฆษณาได้ HTTPS ได้รับการออกแบบมาให้ทนทานต่อการโจมตีประเภทนี้
|
||||
และถือว่าปลอดภัย (ยกเว้นการใช้งาน HTTPS ที่ใช้ SSL เวอร์ชันที่ล้าสมัย)
|
||||
|
||||
=== ชั้นเครือข่าย
|
||||
|
||||
#i HTTP ทำงานที่เลเยอร์สูงสุดของโมเดล TCP/IP นั่นคือเลเยอร์แอปพลิเคชัน เช่นเดียวกับโปรโตคอลความปลอดภัย TLS (ซึ่งทำงานเป็นเลเยอร์ย่อยที่ต่ำกว่าของเลเยอร์เดียวกัน) ซึ่งเข้ารหัสข้อความ HTTP ก่อนส่ง และถอดรหัสเมื่อข้อความมาถึง โดยเคร่งครัดแล้ว HTTPS ไม่ใช่โปรโตคอลใหม่ที่แยกจากกัน แต่หมายถึงการใช้ HTTP ทั่วไปบนการเชื่อมต่อ SSL/TLS ที่เข้ารหัส (เป็นส่วนต่อขยายจาก HTTP อย่างที่กล่าวไปข้างต้น)
|
||||
#iiii HTTP ทำงานที่เลเยอร์สูงสุดของโมเดล TCP/IP นั่นคือเลเยอร์แอปพลิเคชัน#jb
|
||||
เช่นเดียวกับโปรโตคอลความปลอดภัย TLS (ซึ่งทำงานเป็นเลเยอร์ย่อยที่ต่ำกว่าของเลเยอร์เดียวกัน)#jb
|
||||
ซึ่งเข้ารหัสข้อความ HTTP ก่อนส่ง และถอดรหัสเมื่อข้อความมาถึง โดยเคร่งครัดแล้ว HTTPS
|
||||
ไม่ใช่โปรโตคอลใหม่ที่แยกจากกัน แต่หมายถึงการใช้ HTTP ทั่วไปบนการเชื่อมต่อ SSL/TLS ที่เข้ารหัส
|
||||
(เป็นส่วนต่อขยายจาก HTTP อย่างที่กล่าวไปข้างต้น)
|
||||
|
||||
#i HTTPS เข้ารหัสเนื้อหาข้อความทั้งหมด รวมถึงส่วนหัว HTTP และข้อมูลคำขอ/การตอบกลับ ยกเว้นการโจมตีด้วยการเข้ารหัส CCA ที่อาจเกิดขึ้นตามที่อธิบายไว้ในส่วนข้อจำกัดด้านล่าง ผู้โจมตีควรจะสามารถตรวจพบการเชื่อมต่อระหว่างสองฝ่ายได้มากที่สุด รวมถึงชื่อโดเมนและที่อยู่ IP ของฝ่ายนั้นด้วย
|
||||
#iiii HTTPS เข้ารหัสเนื้อหาข้อความทั้งหมด รวมถึงส่วนหัว HTTP และข้อมูลคำขอ/การตอบกลับ
|
||||
ยกเว้นการโจมตีด้วยการเข้ารหัส CCA ที่อาจเกิดขึ้นตามที่อธิบายไว้ในส่วนข้อจำกัดด้านล่าง
|
||||
ผู้โจมตีควรจะสามารถตรวจพบการเชื่อมต่อระหว่างสองฝ่ายได้มากที่สุด รวมถึงชื่อโดเมนและที่อยู่ IP
|
||||
ของฝ่ายนั้นด้วย
|
||||
|
||||
=== การตั้งค่าเซิร์ฟเวอร์
|
||||
|
||||
เพื่อเตรียมเว็บเซิร์ฟเวอร์ให้ยอมรับการเชื่อมต่อ HTTPS ผู้ดูแลระบบต้องสร้างใบรับรองคีย์สาธารณะสำหรับเว็บเซิร์ฟเวอร์ ใบรับรองนี้ต้องได้รับการลงนามโดยผู้ออกใบรับรองที่เชื่อถือได้เพื่อให้เว็บเบราว์เซอร์ยอมรับโดยไม่มีการแจ้งเตือน ผู้ออกใบรับรองจะรับรองว่าผู้ถือใบรับรองคือผู้ดำเนินการของเว็บเซิร์ฟเวอร์ที่นำเสนอใบรับรองนั้น โดยทั่วไปเว็บเบราว์เซอร์จะเผยแพร่รายชื่อใบรับรองการลงนามของผู้ออกใบรับรองหลักๆ เพื่อให้สามารถตรวจสอบใบรับรองที่ลงนามโดยผู้ออกใบรับรองเหล่านั้นได้
|
||||
#iiii เพื่อเตรียมเว็บเซิร์ฟเวอร์ให้ยอมรับการเชื่อมต่อ HTTPS
|
||||
ผู้ดูแลระบบต้องสร้างใบรับรองคีย์สาธารณะสำหรับเว็บเซิร์ฟเวอร์
|
||||
ใบรับรองนี้ต้องได้รับการลงนามโดยผู้ออกใบรับรองที่เชื่อถือได้เพื่อให้เว็บเบราว์เซอร์ยอมรับโดยไม่มีการแจ้งเตือน
|
||||
ผู้ออกใบรับรองจะรับรองว่าผู้ถือใบรับรองคือผู้ดำเนินการของเว็บเซิร์ฟเวอร์ที่นำเสนอใบรับรองนั้น
|
||||
โดยทั่วไปเว็บเบราว์เซอร์จะเผยแพร่รายชื่อใบรับรองการลงนามของผู้ออกใบรับรองหลักๆ
|
||||
เพื่อให้สามารถตรวจสอบใบรับรองที่ลงนามโดยผู้ออกใบรับรองเหล่านั้นได้
|
||||
|
||||
==== การขอใบรับรอง
|
||||
#iiii 1) การขอใบรับรอง
|
||||
|
||||
#i มีผู้ให้บริการออกใบรับรองเชิงพาณิชย์จำนวนหนึ่งที่เสนอใบรับรอง SSL/TLS แบบชำระเงินหลายประเภท รวมถึงใบรับรองการตรวจสอบขยาย
|
||||
#h(8.7em) มีผู้ให้บริการออกใบรับรองเชิงพาณิชย์จำนวนหนึ่งที่เสนอใบรับรอง SSL/TLS
|
||||
แบบชำระเงินหลายประเภท รวมถึงใบรับรองการตรวจสอบขยาย
|
||||
|
||||
#i Let's Encrypt เปิดตัวในเดือนเมษายน 2559 ให้บริการใบรับรอง SSL/TLS พื้นฐานแบบอัตโนมัติฟรีแก่เว็บไซต์ มูลนิธิ Electronic Frontier Foundation ระบุว่า Let's Encrypt จะทำให้การเปลี่ยนจาก HTTP เป็น HTTPS "ง่ายดายเพียงแค่ออกคำสั่งหรือคลิกปุ่ม" ปัจจุบันผู้ให้บริการเว็บโฮสต์และผู้ให้บริการคลาวด์ส่วนใหญ่ใช้ประโยชน์จาก Let's Encrypt เพื่อมอบใบรับรองฟรีให้กับลูกค้า
|
||||
#h(8.7em) Let's Encrypt เปิดตัวในเดือนเมษายน 2559 ให้บริการใบรับรอง SSL/TLS
|
||||
พื้นฐานแบบอัตโนมัติฟรีแก่เว็บไซต์ มูลนิธิ Electronic Frontier Foundation ระบุว่า Let's Encrypt
|
||||
จะทำให้การเปลี่ยนจาก HTTP เป็น HTTPS "ง่ายดายเพียงแค่ออกคำสั่งหรือคลิกปุ่ม"
|
||||
ปัจจุบันผู้ให้บริการเว็บโฮสต์และผู้ให้บริการคลาวด์ส่วนใหญ่ใช้ประโยชน์จาก Let's Encrypt
|
||||
เพื่อมอบใบรับรองฟรีให้กับลูกค้า
|
||||
|
||||
==== ใช้เป็นการควบคุมการเข้าถึง
|
||||
#pagebreak()
|
||||
|
||||
#i ระบบนี้ยังสามารถใช้สำหรับการตรวจสอบสิทธิ์ไคลเอ็นต์เพื่อจำกัดการเข้าถึงเว็บเซิร์ฟเวอร์เฉพาะผู้ใช้ที่ได้รับอนุญาตเท่านั้น ในการดำเนินการนี้ ผู้ดูแลระบบเว็บไซต์มักจะสร้างใบรับรองสำหรับผู้ใช้แต่ละราย ซึ่งผู้ใช้จะโหลดใบรับรองลงในเบราว์เซอร์ โดยปกติใบรับรองจะมีชื่อและที่อยู่อีเมลของผู้ใช้ที่ได้รับอนุญาต และจะถูกตรวจสอบโดยเซิร์ฟเวอร์โดยอัตโนมัติในแต่ละการเชื่อมต่อเพื่อยืนยันตัวตนของผู้ใช้ ซึ่งอาจไม่จำเป็นต้องใช้รหัสผ่านด้วยซ้ำ
|
||||
#iiii 2) ใช้เป็นการควบคุมการเข้าถึง
|
||||
|
||||
==== ในกรณีที่คีย์ลับถูกบุกรุก
|
||||
#h(8.7em)
|
||||
ระบบนี้ยังสามารถใช้สำหรับการตรวจสอบสิทธิ์ไคลเอ็นต์เพื่อจำกัดการเข้าถึงเว็บเซิร์ฟเวอร์เฉพาะผู้ใช้ที่ได้รับอนุญาตเท่านั้น
|
||||
ในการดำเนินการนี้ ผู้ดูแลระบบเว็บไซต์มักจะสร้างใบรับรองสำหรับผู้ใช้แต่ละราย
|
||||
ซึ่งผู้ใช้จะโหลดใบรับรองลงในเบราว์เซอร์ โดยปกติใบรับรองจะมีชื่อและที่อยู่อีเมลของผู้ใช้ที่ได้รับอนุญาต
|
||||
และจะถูกตรวจสอบโดยเซิร์ฟเวอร์โดยอัตโนมัติในแต่ละการเชื่อมต่อเพื่อยืนยันตัวตนของผู้ใช้
|
||||
ซึ่งอาจไม่จำเป็นต้องใช้รหัสผ่านด้วยซ้ำ
|
||||
|
||||
#i คุณสมบัติที่สำคัญในบริบทนี้คือการเข้ารหัสแบบส่งต่อที่สมบูรณ์แบบ (PFS) การมีคีย์ลับแบบอสมมาตรระยะยาวตัวใดตัวหนึ่งที่ใช้สร้างเซสชัน HTTPS ไม่น่าจะทำให้การได้มาซึ่งคีย์เซสชันระยะสั้นเพื่อถอดรหัสการสนทนาทำได้ง่ายขึ้น แม้ในภายหลังก็ตาม ในปี 2013 มีเพียงการแลกเปลี่ยนคีย์ Diffie–Hellman (DHE) และการแลกเปลี่ยนคีย์ Diffie–Hellman แบบเส้นโค้งวงรี (ECDHE) เท่านั้นที่ทราบว่ามีคุณสมบัตินี้ ในปี 2013 มีเพียง 30% ของเซสชัน Firefox, Opera และ Chromium Browser เท่านั้นที่ใช้คุณสมบัตินี้ และเกือบ 0% ของเซสชัน Safari และ Microsoft Internet Explorer ของ Apple ที่ใช้คุณสมบัตินี้ TLS 1.3 ซึ่งเผยแพร่ในเดือนสิงหาคม 2018 ได้ยกเลิกการสนับสนุนการเข้ารหัสแบบไม่มีการเข้ารหัสแบบส่งต่อ ณ เดือนกุมภาพันธ์ พ.ศ. 2562 เว็บเซิร์ฟเวอร์ที่สำรวจ 96.6% รองรับการรักษาความลับแบบ Forward ในรูปแบบใดรูปแบบหนึ่ง และ 52.1% จะใช้การรักษาความลับแบบ Forward กับเบราว์เซอร์ส่วนใหญ่ ณ เดือนกรกฎาคม พ.ศ. 2566 เว็บเซิร์ฟเวอร์ที่สำรวจ 99.6% รองรับการรักษาความลับแบบ Forward ในรูปแบบใดรูปแบบหนึ่ง และ 75.2% จะใช้การรักษาความลับแบบ Forward กับเบราว์เซอร์ส่วนใหญ่
|
||||
#iiii 3) ในกรณีที่คีย์ลับถูกบุกรุก
|
||||
|
||||
===== การเพิกถอนใบรับรอง
|
||||
#h(8.7em) คุณสมบัติที่สำคัญในบริบทนี้คือการเข้ารหัสแบบส่งต่อที่สมบูรณ์แบบ (PFS)
|
||||
การมีคีย์ลับแบบอสมมาตรระยะยาวตัวใดตัวหนึ่งที่ใช้สร้างเซสชัน HTTPS
|
||||
ไม่น่าจะทำให้การได้มาซึ่งคีย์เซสชันระยะสั้นเพื่อถอดรหัสการสนทนาทำได้ง่ายขึ้น แม้ในภายหลังก็ตาม ในปี
|
||||
2013 มีเพียงการแลกเปลี่ยนคีย์ Diffie--Hellman (DHE) และการแลกเปลี่ยนคีย์ Diffie--Hellman
|
||||
แบบเส้นโค้งวงรี#jb (ECDHE) เท่านั้นที่ทราบว่ามีคุณสมบัตินี้ ในปี 2013 มีเพียง 30% ของเซสชัน
|
||||
Firefox, Opera และ#jb Chromium Browser เท่านั้นที่ใช้คุณสมบัตินี้ และเกือบ 0% ของเซสชัน
|
||||
Safari และ Microsoft Internet Explorer ของ Apple ที่ใช้คุณสมบัตินี้ TLS 1.3
|
||||
ซึ่งเผยแพร่ในเดือนสิงหาคม 2018 ได้ยกเลิกการสนับสนุนการเข้ารหัสแบบไม่มีการเข้ารหัสแบบส่งต่อ ณ
|
||||
เดือนกุมภาพันธ์ พ.ศ. 2562 เว็บเซิร์ฟเวอร์ที่สำรวจ 96.6% รองรับการรักษาความลับแบบ Forward
|
||||
ในรูปแบบใดรูปแบบหนึ่ง และ 52.1% จะใช้การรักษาความลับแบบ Forward กับเบราว์เซอร์ส่วนใหญ่ ณ
|
||||
เดือนกรกฎาคม พ.ศ. 2566 เว็บเซิร์ฟเวอร์ที่สำรวจ 99.6% รองรับการรักษาความลับแบบ Forward
|
||||
ในรูปแบบใดรูปแบบหนึ่ง และ 75.2% จะใช้การรักษาความลับแบบ Forward กับเบราว์เซอร์ส่วนใหญ่
|
||||
|
||||
ใบรับรองอาจถูกเพิกถอนก่อนหมดอายุได้ เช่น เนื่องจากความลับของคีย์ส่วนตัวถูกละเมิด เบราว์เซอร์ยอดนิยมเวอร์ชันที่ใหม่พอเช่น Firefox Opera และ Internet Explorer บน Windows Vista จะใช้ Online Certificate Status Protocol (OCSP) เพื่อตรวจสอบว่าไม่เป็นเช่นนั้น เบราว์เซอร์จะส่งหมายเลขซีเรียลของใบรับรองไปยังผู้ออกใบรับรองหรือผู้แทนผ่าน OCSP และผู้ออกใบรับรองจะตอบกลับ โดยแจ้งให้เบราว์เซอร์ทราบว่าใบรับรองยังคงใช้ได้อยู่หรือไม่ นอกจากนี้ CA อาจออกรายการเพิกถอนใบรับรอง (Certificate Revocation List; CRL) เพื่อแจ้งให้ผู้ใช้ทราบว่าใบรับรองเหล่านี้ถูกเพิกถอนแล้ว อย่างไรก็ตาม CRL ไม่จำเป็นสำหรับฟอรัม CA/Browser (“ฟอรัม CA/Browser” ดังกล่าวคือองค์กร) อีกต่อไป อย่างไรก็ตาม CA ยังคงใช้ CRL กันอย่างแพร่หลาย สถานะการเพิกถอนส่วนใหญ่บนอินเทอร์เน็ตจะหายไปในไม่ช้าหลังจากใบรับรองหมดอายุ
|
||||
#iiii 4) การเพิกถอนใบรับรอง
|
||||
|
||||
#h(8.7em) ใบรับรองอาจถูกเพิกถอนก่อนหมดอายุได้ เช่น เนื่องจากความลับของคีย์ส่วนตัวถูกละเมิด
|
||||
เบราว์เซอร์ยอดนิยมเวอร์ชันที่ใหม่พอเช่น Firefox Opera และ Internet Explorer บน Windows
|
||||
Vista จะใช้ Online Certificate Status Protocol (OCSP) เพื่อตรวจสอบว่าไม่เป็นเช่นนั้น
|
||||
เบราว์เซอร์จะส่งหมายเลขซีเรียลของใบรับรองไปยังผู้ออกใบรับรองหรือผู้แทนผ่าน#jb OCSP
|
||||
และผู้ออกใบรับรองจะตอบกลับ โดยแจ้งให้เบราว์เซอร์ทราบว่าใบรับรองยังคงใช้ได้อยู่หรือไม่ นอกจากนี้ CA
|
||||
อาจออกรายการเพิกถอนใบรับรอง (Certificate Revocation List; CRL)
|
||||
เพื่อแจ้งให้ผู้ใช้ทราบว่าใบรับรองเหล่านี้ถูกเพิกถอนแล้ว อย่างไรก็ตาม CRL ไม่จำเป็นสำหรับฟอรัม
|
||||
CA/Browser (“ฟอรัม CA/Browser” ดังกล่าวคือองค์กร) อีกต่อไป อย่างไรก็ตาม CA ยังคงใช้ CRL
|
||||
กันอย่างแพร่หลาย สถานะการเพิกถอนส่วนใหญ่บนอินเทอร์เน็ตจะหายไปในไม่ช้าหลังจากใบรับรองหมดอายุ
|
||||
|
||||
=== ข้อจำกัด
|
||||
|
||||
#i การเข้ารหัส SSL (Secure Sockets Layer) และ TLS (Transport Layer Security) สามารถกำหนดค่าได้สองโหมด ได้แก่ โหมดธรรมดาและโหมด Mutual ในโหมดธรรมดา การตรวจสอบสิทธิ์จะดำเนินการโดยเซิร์ฟเวอร์เท่านั้น โหมด Mutual กำหนดให้ผู้ใช้ต้องติดตั้งใบรับรองไคลเอ็นต์ส่วนบุคคลในเว็บเบราว์เซอร์เพื่อการตรวจสอบสิทธิ์ผู้ใช้ ไม่ว่าในกรณีใด ระดับการป้องกันจะขึ้นอยู่กับความถูกต้องของการใช้งานซอฟต์แวร์และอัลกอริทึมการเข้ารหัสที่ใช้
|
||||
#iiii การเข้ารหัส SSL (Secure Sockets Layer) และ TLS (Transport Layer Security)
|
||||
สามารถกำหนดค่าได้สองโหมด ได้แก่ โหมดธรรมดาและโหมด Mutual ในโหมดธรรมดา
|
||||
การตรวจสอบสิทธิ์จะดำเนินการโดยเซิร์ฟเวอร์เท่านั้น โหมด Mutual
|
||||
กำหนดให้ผู้ใช้ต้องติดตั้งใบรับรองไคลเอ็นต์ส่วนบุคคลในเว็บเบราว์เซอร์เพื่อการตรวจสอบสิทธิ์ผู้ใช้
|
||||
ไม่ว่าในกรณีใด
|
||||
ระดับการป้องกันจะขึ้นอยู่กับความถูกต้องของการใช้งานซอฟต์แวร์และอัลกอริทึมการเข้ารหัสที่ใช้
|
||||
|
||||
#i SSL/TLS ไม่ป้องกันการจัดทำดัชนีของเว็บไซต์โดยเว็บครอว์เลอร์ และในบางกรณี URI ของทรัพยากรที่เข้ารหัสสามารถอนุมานได้โดยการทราบขนาดคำขอ/การตอบสนองที่ถูกสกัดกั้นเท่านั้น วิธีนี้ช่วยให้ผู้โจมตีสามารถเข้าถึงข้อความธรรมดา (เนื้อหาคงที่ที่เปิดเผยต่อสาธารณะ) และข้อความที่เข้ารหัส (เนื้อหาคงที่เวอร์ชันเข้ารหัส) ทำให้สามารถโจมตีด้วยการเข้ารหัสได้
|
||||
#iiii SSL/TLS ไม่ป้องกันการจัดทำดัชนีของเว็บไซต์โดยเว็บครอว์เลอร์ และในบางกรณี URI
|
||||
ของทรัพยากรที่เข้ารหัสสามารถอนุมานได้โดยการทราบขนาดคำขอ/การตอบสนองที่ถูกสกัดกั้นเท่านั้น
|
||||
วิธีนี้ช่วยให้ผู้โจมตีสามารถเข้าถึงข้อความธรรมดา (เนื้อหาคงที่ที่เปิดเผยต่อสาธารณะ) และข้อความที่เข้ารหัส
|
||||
(เนื้อหาคงที่เวอร์ชันเข้ารหัส) ทำให้สามารถโจมตีด้วยการเข้ารหัสได้
|
||||
|
||||
#i เนื่องจาก TLS ทำงานที่ระดับโปรโตคอลที่ต่ำกว่า HTTP และไม่มีความรู้เกี่ยวกับโปรโตคอลระดับสูงกว่า เซิร์ฟเวอร์ TLS จึงสามารถแสดงใบรับรองได้เพียงใบเดียวสำหรับที่อยู่และพอร์ตที่กำหนดเท่านั้น ในอดีต นั่นหมายความว่าไม่สามารถใช้การโฮสต์เสมือนแบบอิงชื่อกับ HTTPS ได้ มีโซลูชันที่เรียกว่า Server Name Indication (SNI) ซึ่งส่งชื่อโฮสต์ไปยังเซิร์ฟเวอร์ก่อนเข้ารหัสการเชื่อมต่อ แม้ว่าเบราว์เซอร์รุ่นเก่าจะไม่รองรับส่วนขยายนี้ก็ตาม การรองรับ SNI มีให้ใช้งานตั้งแต่ Firefox 2, Opera 8, Apple Safari 2.1, Google Chrome 6 และ Internet Explorer 7 บน Windows Vista
|
||||
#iiii เนื่องจาก TLS ทำงานที่ระดับโปรโตคอลที่ต่ำกว่า HTTP
|
||||
และไม่มีความรู้เกี่ยวกับโปรโตคอลระดับสูงกว่า เซิร์ฟเวอร์ TLS
|
||||
จึงสามารถแสดงใบรับรองได้เพียงใบเดียวสำหรับที่อยู่และพอร์ตที่กำหนดเท่านั้น ในอดีต
|
||||
นั่นหมายความว่าไม่สามารถใช้การโฮสต์เสมือนแบบอิงชื่อกับ HTTPS ได้ มีโซลูชันที่เรียกว่า Server Name
|
||||
Indication (SNI) ซึ่งส่งชื่อโฮสต์ไปยังเซิร์ฟเวอร์ก่อนเข้ารหัสการเชื่อมต่อ
|
||||
แม้ว่าเบราว์เซอร์รุ่นเก่าจะไม่รองรับส่วนขยายนี้ก็ตาม การรองรับ SNI มีให้ใช้งานตั้งแต่ Firefox 2,
|
||||
Opera 8, Apple Safari 2.1, Google Chrome 6 และ Internet Explorer 7 บน Windows
|
||||
Vista
|
||||
|
||||
#i การโจมตีแบบ man-in-the-middle ที่ซับซ้อนประเภทหนึ่งที่เรียกว่า SSL stripping ถูกนำเสนอในงานประชุม Blackhat Conference ปี 2009 การโจมตีประเภทนี้ทำลายความปลอดภัยของ HTTPS โดยการเปลี่ยนลิงก์ https: ให้เป็นลิงก์ http: โดยใช้ประโยชน์จากข้อเท็จจริงที่ว่าผู้ใช้อินเทอร์เน็ตเพียงไม่กี่คนเท่านั้นที่พิมพ์ "https" ลงในอินเทอร์เฟซเบราว์เซอร์ พวกเขาจึงเข้าสู่เว็บไซต์ที่ปลอดภัยได้โดยการคลิกลิงก์ และถูกหลอกให้คิดว่ากำลังใช้ HTTPS ในขณะที่จริงๆ แล้วกำลังใช้ HTTP ผู้โจมตีจึงสื่อสารกับไคลเอ็นต์อย่างชัดเจน สิ่งนี้กระตุ้นให้เกิดการพัฒนามาตรการรับมือใน HTTP ที่เรียกว่า HTTP Strict Transport Security
|
||||
#iiii การโจมตีแบบ man-in-the-middle ที่ซับซ้อนประเภทหนึ่งที่เรียกว่า SSL stripping
|
||||
ถูกนำเสนอในงานประชุม Blackhat Conference ปี 2009 การโจมตีประเภทนี้ทำลายความปลอดภัยของ
|
||||
HTTPS โดยการเปลี่ยนลิงก์ https: ให้เป็นลิงก์ http:
|
||||
โดยใช้ประโยชน์จากข้อเท็จจริงที่ว่าผู้ใช้อินเทอร์เน็ตเพียงไม่กี่คนเท่านั้นที่พิมพ์ "https"
|
||||
ลงในอินเทอร์เฟซเบราว์เซอร์ พวกเขาจึงเข้าสู่เว็บไซต์ที่ปลอดภัยได้โดยการคลิกลิงก์
|
||||
และถูกหลอกให้คิดว่ากำลังใช้ HTTPS ในขณะที่จริงๆ แล้วกำลังใช้ HTTP
|
||||
ผู้โจมตีจึงสื่อสารกับไคลเอ็นต์อย่างชัดเจน สิ่งนี้กระตุ้นให้เกิดการพัฒนามาตรการรับมือใน HTTP ที่เรียกว่า
|
||||
HTTP Strict Transport Security
|
||||
|
||||
#i HTTPS ได้รับการพิสูจน์แล้วว่ามีความเสี่ยงต่อการโจมตีวิเคราะห์ทราฟฟิกหลากหลายรูปแบบ การโจมตีวิเคราะห์ทราฟฟิกเป็นการโจมตีแบบ Side-Channel ประเภทหนึ่งที่อาศัยการเปลี่ยนแปลงเวลาและขนาดของทราฟฟิกเพื่ออนุมานคุณสมบัติของทราฟฟิกที่เข้ารหัส การวิเคราะห์ทราฟฟิกเป็นไปได้เนื่องจากการเข้ารหัส SSL/TLS เปลี่ยนแปลงเนื้อหาของทราฟฟิก แต่มีผลกระทบน้อยมากต่อขนาดและระยะเวลาของทราฟฟิก ในเดือนพฤษภาคม 2553 งานวิจัยโดยนักวิจัยจาก Microsoft Research และ Indiana University ค้นพบว่าข้อมูลผู้ใช้ที่ละเอียดอ่อนโดยละเอียดสามารถอนุมานได้จากช่องทางด้านข้าง เช่น ขนาดแพ็กเก็ต นักวิจัยพบว่าแม้จะมีการป้องกัน HTTPS ในแอปพลิเคชันเว็บชั้นนำที่มีชื่อเสียงหลายตัวในด้านการดูแลสุขภาพ ภาษี การลงทุน และการค้นหาเว็บ แต่ผู้แอบฟังสามารถอนุมานโรค/ยา/การผ่าตัดของผู้ใช้ รายได้ของครอบครัว และความลับในการลงทุนได้
|
||||
#iiii HTTPS ได้รับการพิสูจน์แล้วว่ามีความเสี่ยงต่อการโจมตีวิเคราะห์ทราฟฟิกหลากหลายรูปแบบ
|
||||
การโจมตีวิเคราะห์ทราฟฟิกเป็นการโจมตีแบบ Side-Channel
|
||||
ประเภทหนึ่งที่อาศัยการเปลี่ยนแปลงเวลาและขนาดของทราฟฟิกเพื่ออนุมานคุณสมบัติของทราฟฟิกที่เข้ารหัส
|
||||
การวิเคราะห์ทราฟฟิกเป็นไปได้เนื่องจากการเข้ารหัส SSL/TLS เปลี่ยนแปลงเนื้อหาของทราฟฟิก
|
||||
แต่มีผลกระทบน้อยมากต่อขนาดและระยะเวลาของทราฟฟิก ในเดือนพฤษภาคม 2553 งานวิจัยโดยนักวิจัยจาก
|
||||
Microsoft Research และ Indiana University
|
||||
ค้นพบว่าข้อมูลผู้ใช้ที่ละเอียดอ่อนโดยละเอียดสามารถอนุมานได้จากช่องทางด้านข้าง เช่น ขนาดแพ็กเก็ต
|
||||
นักวิจัยพบว่าแม้จะมีการป้องกัน HTTPS ในแอปพลิเคชันเว็บชั้นนำที่มีชื่อเสียงหลายตัวในด้านการดูแลสุขภาพ
|
||||
ภาษี การลงทุน และการค้นหาเว็บ แต่ผู้แอบฟังสามารถอนุมานโรค/ยา/การผ่าตัดของผู้ใช้
|
||||
รายได้ของครอบครัว และความลับในการลงทุนได้
|
||||
|
||||
#i ความจริงที่ว่าเว็บไซต์สมัยใหม่ส่วนใหญ่ รวมถึง Google, Yahoo! และ Amazon ใช้ HTTPS ทำให้เกิดปัญหาสำหรับผู้ใช้จำนวนมากที่พยายามเข้าถึงจุดเชื่อมต่อ Wi-Fi สาธารณะ เนื่องจากหน้าเข้าสู่ระบบจุดเชื่อมต่อ Wi-Fi ของพอร์ทัลแบบแคปทีฟไม่สามารถโหลดได้หากผู้ใช้พยายามเปิดทรัพยากร HTTPS และเว็บไซต์หลายแห่ง เช่น NeverSSL รับประกันว่าเว็บไซต์เหล่านั้นจะสามารถเข้าถึงได้ผ่าน HTTP เสมอ
|
||||
#iiii ความจริงที่ว่าเว็บไซต์สมัยใหม่ส่วนใหญ่ รวมถึง Google, Yahoo! และ Amazon ใช้ HTTPS
|
||||
ทำให้เกิดปัญหาสำหรับผู้ใช้จำนวนมากที่พยายามเข้าถึงจุดเชื่อมต่อ Wi-Fi สาธารณะ
|
||||
เนื่องจากหน้าเข้าสู่ระบบจุดเชื่อมต่อ Wi-Fi
|
||||
ของพอร์ทัลแบบแคปทีฟไม่สามารถโหลดได้หากผู้ใช้พยายามเปิดทรัพยากร HTTPS และเว็บไซต์หลายแห่ง เช่น
|
||||
NeverSSL รับประกันว่าเว็บไซต์เหล่านั้นจะสามารถเข้าถึงได้ผ่าน HTTP เสมอ
|
||||
|
||||
@@ -1,41 +1,49 @@
|
||||
#import "../PageTemplate.typ": chapter-page, i, jb
|
||||
#show: chapter-page
|
||||
#set enum(indent: 3em, numbering: n => "2." + str(n))
|
||||
|
||||
#heading([#linebreak()ทฤษฎีและเอกสารที่เกี่ยวข้อง])
|
||||
|
||||
#i ผู้จัดทำโครงงาน#h(1em)เครื่องยืนยันตัวตนด้วย NFC#h(1em)ได้ศึกษาทฤษฎีที่เกี่ยวข้องต่าง ๆ และ\
|
||||
#i ผู้จัดทำโครงงาน เครื่องยืนยันตัวตนด้วย NFC ได้ศึกษาทฤษฎีที่เกี่ยวข้องต่าง ๆ และ#jb
|
||||
รวบรวมแนวทางและหลักการต่าง ๆ จากเอกสารงานวิจัยที่เกี่ยวข้องดังต่อไปนี้
|
||||
|
||||
+ ไมโครคอนโทรเลอร์ (Microcontroller)
|
||||
+ เซ็นเซอร์ (Sensors)
|
||||
+ ลำโพงสัญญาณ (Buzzer)
|
||||
+ เกณฑ์วิธีขนส่งข้อความหลายมิติ (HyperText Transfer Protocol; HTTP)
|
||||
+ เกณฑ์วิธีขนส่งข้อความหลายมิติแบบมั่นคง (Hypertext Transfer Protocol Secure; HTTPS)
|
||||
+ เกณฑ์วิธีความมั่นคงของชั้นขนส่ง (Transport Layer Security; TLS)
|
||||
+ การสื่อสารสนามใกล้ (Near-field communication; NFC)
|
||||
+ Flutter
|
||||
+ Git
|
||||
+ ภาษาซี (C Programming Language)
|
||||
#block(inset: (left: 3em))[
|
||||
2.1 ไมโครคอนโทรเลอร์ (Microcontroller)\
|
||||
2.2 เซ็นเซอร์ (Sensors)\
|
||||
2.3 ลำโพงสัญญาณ (Buzzer)\
|
||||
2.4 เกณฑ์วิธีขนส่งข้อความหลายมิติ (HyperText Transfer Protocol; HTTP)\
|
||||
2.5 เกณฑ์วิธีขนส่งข้อความหลายมิติแบบมั่นคง (Hypertext Transfer Protocol Secure; HTTPS)\
|
||||
2.6 เกณฑ์วิธีความมั่นคงของชั้นขนส่ง (Transport Layer Security; TLS)\
|
||||
2.7 การสื่อสารสนามใกล้ (Near-field communication; NFC)\
|
||||
2.8 Flutter\
|
||||
2.9 Git\
|
||||
2.10 ภาษาซี (C Programming Language)
|
||||
]
|
||||
|
||||
#set heading(numbering: "1.1")
|
||||
#counter(heading).update((2, 0))
|
||||
|
||||
== ไมโครคอนโทรเลอร์ (Microcontroller)
|
||||
|
||||
#i ความรู้เกี่ยวกับไมโครคอนโทรลเลอร์เบื้องต้น ไมโครคอนโทรลเลอร์ (มักย่อว่า uC หรือ MCU) คือ
|
||||
อุปกรณ์ควบคุมขนาดเล็ก ซึ่งบรรจุความสามารถที่คล้ายคลึงกับระบบคอมพิวเตอร์ โดยใน
|
||||
ไมโครคอนโทรลเลอร์ได้รวม เอาซีพียูหน่วยความจำและพอร์ต ซึ่งเป็นส่วนประกอบหลักสำคัญของ
|
||||
ระบบคอมพิวเตอร์เข้าไว้ด้วยกัน โดยทำการบรรจุเข้าไว้ในตัวถังเดียวกัน ไมโครคอนโทรลเลอร์ถ้าแปล
|
||||
ความหมายแบบตรงตัวก็คือ ระบบคอนโทรลขนาดเล็กเรียกอีกอย่างหนึ่งคือเป็นระบบคอมพิวเตอร์ ขนาดเล็ก
|
||||
ที่สามารถนำมาประยุกต์ใช้งานได้หลากหลาย โดยผ่านการออกแบบวงจรให้เหมาะกับงาน ต่างๆ
|
||||
และยังสามารถเขียนโปรแกรมคำสั่งเพื่อควบคุมขา Input/Output เพื่อสั่งงานให้ไป ควบคุม อุปกรณ์ต่างๆ
|
||||
ได้อีกด้วย ซึ่งก็นับว่าเป็นระบบที่สามารถนำมาประยุกต์ใช้งานได้หลากหลาย ทั้ง ทางด้าน Digital และ
|
||||
Analog ยกตัวอย่างเช่น ระบบสัญญาณตอบรับอัตโนมัติ, ระบบบัตรคิว, ระบบ ตอกบัตรพนักงาน และอื่นๆ
|
||||
ยิ่งระบบไมโครคอนโทรลเลอร์ในยุคปัจจุบันนั้นสามารถทำการเชื่อต่อกับ ระบบ Network
|
||||
ของคอมพิวเตอร์ทั่วไปได้อีกด้วย ดังนั้นการสั่งงานจึงไม่ใช่แค่หน้าแผงวงจร แต่ อาจจะเป็นการสั่งงานอยู่คนละ
|
||||
ซีกโลกผ่านเครือข่ายอินเตอร์เน็ตก็ได้โครงสร้างโดยทั่วไปของไมโครคอนโทรลเลอร์นั้น
|
||||
สามารถแบ่งออกมาได้เป็น 5 ส่วนใหญ่ ๆ ได้แก่ หน่วยประมวลผลกลาง หรือ ซีพียู, หน่วยความจำ,
|
||||
ส่วนติดต่อกับอุปกรณ์ภายนอก หรือพอร์ต, ช่องทางเดินของสัญญาณ หรือบัส และ วงจรกำเนิดสัญญาณนาฬิกา#jb
|
||||
หน่วยความจำนั้น สามารถแบ่งออกเป็น 2 ส่วนคือ หน่วยความจำที่มีไว้สำหรับเก็บ โปรแกรมหลัก
|
||||
เปรียบเสมือนฮาร์ดดิสก์และหน่วยความจำข้อมูล ใช้เป็นเหมือนกับ กระดาษทดในการ คำนวณของ#jb
|
||||
#h(1.7em) ไมโครคอนโทรลเลอร์ (Microcontroller, MC, uC, หรือ #(sym.mu)C)
|
||||
หรือหน่วยไมโครคอนโทรลเลอร์ (Microcontroller Unit; MCU)
|
||||
เป็นคอมพิวเตอร์ขนาดเล็กบนวงจรรวมเดียว (Integrated Circuit; IC)
|
||||
โดยไมโครคอนโทรลเลอร์ประกอบด้วยแกนประมวลผลหนึ่งแกนหรือมากกว่า
|
||||
พร้อมด้วยหน่วยความจำและอุปกรณ์ต่อพ่วงอินพุต/เอาต์พุตที่ตั้งโปรแกรมได้
|
||||
หน่วยความจำโปรแกรมในรูปแบบของ NOR flash, OTP ROM, หรือ ferroelectric RAM
|
||||
มักจะถูกรวมไว้ในชิปด้วยเช่นกัน รวมถึง RAM จำนวนเล็กน้อย#jb
|
||||
ไมโครคอนโทรลเลอร์ได้รับการออกแบบมาสำหรับการใช้งานแบบฝังตัว
|
||||
ซึ่งแตกต่างจากไมโครโปรเซสเซอร์ที่ใช้ในคอมพิวเตอร์ส่วนบุคคลหรือแอปพลิเคชันทั่วไปอื่น ๆ
|
||||
ที่ประกอบด้วยชิปแยกชิ้นต่าง ๆ
|
||||
|
||||
#h(1.7em) ในศัพท์สมัยใหม่ ไมโครคอนโทรลเลอร์นั้นคล้ายคลึงกับระบบบนชิป (System on a chip;
|
||||
SoC) แต่มีความซับซ้อนน้อยกว่า SoC อาจมีไมโครคอนโทรลเลอร์เป็นส่วนประกอบหนึ่ง
|
||||
แต่โดยทั่วไปแล้วจะรวมเข้ากับอุปกรณ์ต่อพ่วงขั้นสูง เช่น หน่วยประมวลผลกราฟิก (GPU) โมดูล Wi-Fi
|
||||
หรือตัวประมวลผลร่วม (coprocessor) อย่างน้อยหนึ่งตัว
|
||||
|
||||
#h(1.7em) ไมโครคอนโทรลเลอร์ถูกนำไปใช้ในผลิตภัณฑ์และอุปกรณ์ควบคุมอัตโนมัติ เช่น
|
||||
ระบบควบคุมเครื่องยนต์รถยนต์ อุปกรณ์ทางการแพทย์ที่ฝังในร่างกาย รีโมทคอนโทรล เครื่องใช้สำนักงาน
|
||||
เครื่องใช้ไฟฟ้า#jb เครื่องมือไฟฟ้า ของเล่น และระบบฝังตัวอื่น ๆ
|
||||
การลดขนาดและต้นทุนเมื่อเทียบกับการออกแบบที่ใช้ไมโครโปรเซสเซอร์ หน่วยความจำ
|
||||
และอุปกรณ์อินพุต/เอาต์พุตแยกต่างหาก ทำให้การควบคุมแบบดิจิทัลสำหรับอุปกรณ์และกระบวนการต่าง ๆ
|
||||
เป็นไปได้มากขึ้น ไมโครคอนโทรลเลอร์แบบผสมสัญญาณเป็นที่นิยม
|
||||
โดยจะรวมส่วนประกอบอนาล็อกที่จำเป็นในการควบคุมระบบอิเล็กทรอนิกส์ที่ไม่ใช่ดิจิทัล#jb
|
||||
|
||||
@@ -1,146 +1,382 @@
|
||||
#import "../PageTemplate.typ": i, jb
|
||||
#import "../PageTemplate.typ": *
|
||||
|
||||
ซีพียู โดย ESP32 เป็นไมโครคอนโทรลเลอร์แบบ System-on-a-Chip (SoC)
|
||||
ที่มีการรวมส่วนประกอบทั้งหมดที่จำเป็นสำหรับการประมวลผลและการสื่อสารไร้สายไว้ในชิปเดียว
|
||||
ที่มีคุณสมบัติเด่นด้านการเชื่อมต่อ Wi-Fi และ Bluetooth ในตัว เป็นชิปไมโครคอนโทรลเลอร์แบบ 32 บิต
|
||||
ที่มีความสามารถสูง พัฒนาและผลิตโดย บริษัท Espressif Systems จากประเทศจีน
|
||||
ส่วนประกอบหลักของบอร์ด ESP32
|
||||
ในบริบทของ Internet of Things (IoT) ไมโครคอนโทรลเลอร์เป็นวิธีการรวบรวมข้อมูล การตรวจจับ
|
||||
และการกระตุ้นโลกทางกายภาพในฐานะอุปกรณ์ปลายทางที่มีราคาประหยัดและเป็นที่นิยม
|
||||
|
||||
#i ESP32 คือ ไมโครคอนโทรลเลอร์ราคาประหยัดและประหยัดพลังงานที่ผสานรวมความสามารถทั้ง Wi-Fi
|
||||
และ Bluetooth ชิปเหล่านี้มีตัวเลือกการประมวลผลที่หลากหลาย รวมถึง ไมโครโปรเซสเซอร์#jb
|
||||
Tensilica Xtensa LX6 ที่มีทั้งแบบดูอัลคอร์และแบบซิงเกิลคอร์ โปรเซสเซอร์ดูอัลคอร์ Xtensa LX7 หรือ
|
||||
ไมโครโปรเซสเซอร์ RISC-V แบบซิงเกิลคอร์ นอกจากนี้ ESP32
|
||||
ยังมีส่วนประกอบที่จำเป็นสำหรับการสื่อสารข้อมูลไร้สาย เช่น สวิตช์เสาอากาศในตัว บาลัน RF
|
||||
เครื่องขยายสัญญาณ ตัวรับสัญญาณเสียงรบกวนต่ำ ตัวกรอง และโมดูลจัดการพลังงาน
|
||||
#h(1.7em) ไมโครคอนโทรลเลอร์บางตัวอาจใช้คำแบบสี่บิตและทำงานที่ความถี่ต่ำถึง 4 kHz
|
||||
เพื่อการใช้พลังงานต่ำ (มิลลิวัตต์หรือไมโครวัตต์หลักเดียว) โดยทั่วไปแล้ว
|
||||
ไมโครคอนโทรลเลอร์เหล่านี้สามารถคงการทำงานไว้ได้ในขณะที่รอเหตุการณ์ เช่น
|
||||
การกดปุ่มหรือการขัดจังหวะอื่นๆ การใช้พลังงานขณะอยู่ในโหมดสลีป (โดยที่นาฬิกา CPU
|
||||
และอุปกรณ์ต่อพ่วงส่วนใหญ่ปิดอยู่) อาจอยู่ที่ระดับนาโนวัตต์เท่านั้น#jb
|
||||
ทำให้หลายตัวเหมาะสำหรับแอปพลิเคชันที่ใช้แบตเตอรี่ได้นาน ส่วนไมโครคอนโทรลเลอร์อื่นๆ
|
||||
อาจทำหน้าที่ในบทบาทที่สำคัญต่อประสิทธิภาพ ซึ่งอาจต้องทำงานคล้ายกับตัวประมวลผลสัญญาณดิจิทัล (Digital
|
||||
Signal Processor; DSP) โดยมีความเร็วสัญญาณนาฬิกาและการใช้พลังงานที่สูงกว่า
|
||||
|
||||
#i โดยทั่วไป ESP32 จะถูกฝังอยู่บนแผงวงจรพิมพ์เฉพาะอุปกรณ์ หรือนำเสนอเป็นส่วนหนึ่งของชุดพัฒนาที่มี
|
||||
พินและขั้วต่อ GPIO หลากหลายรูป แบบ โดยมีการกำหนดค่าแตกต่างกันไปตามรุ่นและผู้ผลิต ESP32
|
||||
ออกแบบโดย Espressif Systems และผลิตโดย TSMC โดยใช้กระบวนการ 40
|
||||
นาโนเมตรเป็นรุ่นต่อยอดจากไมโครคอนโทรลเลอร์ ESP8266
|
||||
== ประวัติ
|
||||
|
||||
#i นับตั้งแต่เปิดตัว ESP32 รุ่นดั้งเดิม มีการเปิดตัวและประกาศรุ่นต่างๆ มากมาย
|
||||
พวกมันรวมกันเป็นไมโครคอนโทรลเลอร์ตระกูล ESP32 ชิปเหล่านี้มี CPU และความสามารถที่แตกต่างกัน
|
||||
แต่ทั้งหมดใช้ SDK เดียวกันและส่วนใหญ่เข้ากันได้กับโค้ด นอกจากนี้ ESP32 รุ่นดั้งเดิมยังได้รับการปรับปรุง
|
||||
และส่วนประกอบหลักของบอร์ด ESP32 คือ ไมโครโปรเซสเซอร์ LX6 32 บิตแบบคอร์เดี่ยว/คู่ Xtensa
|
||||
รองรับหน่วยจุดลอยตัวความแม่นยำเดี่ยว (FPU) ไวไฟ: 802.11b/g/n บลูทูธ: v4.2 BR/EDR และ BLE
|
||||
(แชร์วิทยุกับ Wi-Fi) GPIO จำนวน 34 ตัว ADC SAR #math.equation(
|
||||
$2 times 12$,
|
||||
alt: "2 คูณ 12",
|
||||
) บิต สูงสุด 18 ช่องและ #math.equation($2 times 8$, alt: "2 คูณ 8") บิต DAC
|
||||
#iii ไมโครโปรเซสเซอร์แบบหลายชิปตัวแรก ได้แก่ Four-Phase Systems AL1 ในปี 1969 และ#jb
|
||||
Garrett AiResearch MP944 ในปี 1970 ซึ่งถูกพัฒนาขึ้นโดยใช้ชิป MOS LSI หลายตัว
|
||||
ส่วนไมโครโปรเซสเซอร์แบบชิปเดี่ยวตัวแรกคือ Intel 4004 ซึ่งวางจำหน่ายในปี 1971 โดยใช้ชิป MOS
|
||||
LSI เพียงตัวเดียว พัฒนาโดย Federico Faggin โดยใช้เทคโนโลยี MOS แบบซิลิคอนเกต
|
||||
ร่วมกับวิศวกรของ#jb Intel คือ Marcian Hoff และ Stan Mazor และวิศวกรของ Busicom คือ
|
||||
Masatoshi Shima ต่อมาก็มี Intel 4040 แบบ 4 บิต, Intel 8008 แบบ 8 บิต, และ Intel 8080
|
||||
แบบ 8 บิต โปรเซสเซอร์เหล่านี้ทั้งหมดต้องการชิปภายนอกหลายตัวเพื่อสร้างระบบที่ใช้งานได้
|
||||
รวมถึงชิปหน่วยความจำและชิปอินเทอร์เฟซอุปกรณ์ต่อพ่วง
|
||||
ส่งผลให้ต้นทุนของระบบโดยรวมสูงถึงหลายร้อยดอลลาร์สหรัฐ (ในทศวรรษ 1970)
|
||||
ทำให้การนำคอมพิวเตอร์มาใช้กับเครื่องใช้ไฟฟ้าขนาดเล็กนั้นไม่คุ้มค่าทางเศรษฐกิจ
|
||||
|
||||
#iii บริษัท MOS Technology เปิดตัวไมโครโปรเซสเซอร์ราคาต่ำกว่า 100 ดอลลาร์ในปี 1975 ได้แก่รุ่น
|
||||
6501 และ 6502 จุดประสงค์หลักคือการลดอุปสรรคด้านราคา
|
||||
แต่ไมโครโปรเซสเซอร์เหล่านี้ยังคงต้องการการสนับสนุนจากภายนอก หน่วยความจำ และชิปอุปกรณ์ต่อพ่วง
|
||||
ซึ่งทำให้ต้นทุนรวมของระบบยังคงอยู่ในระดับหลายร้อยดอลลาร์
|
||||
|
||||
=== การพัฒนา
|
||||
|
||||
#iiii หนังสือเล่มหนึ่งระบุว่า Gary Boone และ Michael Cochran วิศวกรของบริษัท TI
|
||||
ประสบความสำเร็จในการสร้างไมโครคอนโทรลเลอร์ตัวแรกในปี 1971 ผลงานของพวกเขาคือ TMS 1000
|
||||
ซึ่งวางจำหน่ายในเชิงพาณิชย์ในปี 1974 ไมโครคอนโทรลเลอร์นี้รวมหน่วยความจำแบบอ่านอย่างเดียว
|
||||
หน่วยความจำแบบทั้งอ่านและเขียน โปรเซสเซอร์ และนาฬิกาไว้ในชิปเดียว และมุ่งเป้าไปที่ระบบฝังตัว
|
||||
|
||||
#iiii ในช่วงต้นถึงกลางทศวรรษ 1970
|
||||
ผู้ผลิตอุปกรณ์อิเล็กทรอนิกส์ของญี่ปุ่นเริ่มผลิตไมโครคอนโทรลเลอร์สำหรับรถยนต์ ซึ่งรวมถึง MCU 4
|
||||
บิตสำหรับระบบความบันเทิงในรถยนต์ ที่ปัดน้ำฝนอัตโนมัติ ระบบล็อคอิเล็กทรอนิกส์ และแผงหน้าปัด ตลอดจน
|
||||
MCU 8 บิตสำหรับควบคุมเครื่องยนต์
|
||||
|
||||
#iiii ส่วนหนึ่งเพื่อตอบสนองต่อการมีอยู่ของชิป TMS 1000 แบบชิปเดี่ยว Intel
|
||||
จึงพัฒนาชิปประมวลผลระบบคอมพิวเตอร์บนชิปที่ปรับให้เหมาะสมสำหรับการใช้งานด้านการควบคุม นั่นคือ#jb
|
||||
Intel 8048 โดยเริ่มจัดส่งชิ้นส่วนเชิงพาณิชย์ครั้งแรกในปี 1977 ชิปนี้รวม RAM และ ROM
|
||||
ไว้ในชิปเดียวกันกับไมโครโปรเซสเซอร์ ในบรรดาแอปพลิเคชันมากมาย
|
||||
ชิปนี้ได้ถูกนำไปใช้ในแป้นพิมพ์พีซีมากกว่าหนึ่งพันล้านเครื่องในที่สุด ในเวลานั้น Luke J. Valenter
|
||||
ประธานของ Intel
|
||||
กล่าวว่าไมโครคอนโทรลเลอร์เป็นหนึ่งในผลิตภัณฑ์ที่ประสบความสำเร็จมากที่สุดในประวัติศาสตร์ของบริษัท
|
||||
และเขาได้ขยายงบประมาณของแผนกไมโครคอนโทรลเลอร์เพิ่มขึ้นกว่า 25%
|
||||
|
||||
#iiii ไมโครคอนโทรลเลอร์ส่วนใหญ่ในเวลานั้นมีหลายรุ่นที่ใช้งานพร้อมกัน รุ่นหนึ่งใช้หน่วยความจำโปรแกรม
|
||||
EPROM
|
||||
โดยมีหน้าต่างควอตซ์โปร่งใสอยู่ที่ฝาปิดของตัวชิปเพื่อให้สามารถลบข้อมูลได้โดยการฉายแสงอัลตราไวโอเลต
|
||||
ชิปที่ลบได้เหล่านี้มักใช้สำหรับการสร้างต้นแบบ อีกรุ่นหนึ่งคือ ROM ที่ตั้งโปรแกรมด้วยมาสก์ หรือ PROM
|
||||
ที่ตั้งโปรแกรมได้เพียงครั้งเดียว สำหรับรุ่นหลัง บางครั้งจะใช้คำว่า#jb OTP ซึ่งย่อมาจาก "one-time
|
||||
programmable" (ตั้งโปรแกรมได้ครั้งเดียว) ในไมโครคอนโทรลเลอร์#jb OTP นั้น PROM
|
||||
มักจะเป็นชนิดเดียวกับ EPROM แต่ตัวชิปไม่มีหน้าต่างควอตซ์
|
||||
เนื่องจากไม่มีวิธีใดที่จะฉายแสงอัลตราไวโอเลตไปยัง EPROM ได้ จึงไม่สามารถลบข้อมูลได้
|
||||
เนื่องจากรุ่นที่ลบได้ต้องใช้ตัวชิปเซรามิกที่มีหน้าต่างควอตซ์ จึงมีราคาแพงกว่ารุ่น OTP อย่างมาก
|
||||
ซึ่งสามารถผลิตได้ในตัวชิปพลาสติกทึบแสงที่มีราคาถูกกว่า สำหรับรุ่นที่สามารถลบได้นั้น
|
||||
จำเป็นต้องใช้ควอตซ์แทนกระจกที่มีราคาถูกกว่า#jb เนื่องจากมีความโปร่งใสต่อแสงอัลตราไวโอเลต
|
||||
ซึ่งกระจกส่วนใหญ่ทึบแสง แต่ปัจจัยหลักที่ทำให้ต้นทุนแตกต่างกันคือตัวบรรจุภัณฑ์เซรามิกเอง
|
||||
นอกจากนี้ยังมีการใช้ไมโครคอนโทรลเลอร์แบบ Piggyback ด้วย
|
||||
|
||||
#afigure(
|
||||
image("Microcontroller/PIC16CxxxWIN.jpg", height: 2.5in),
|
||||
attr: [Camillo - Own work, CC BY 2.5,
|
||||
https://commons.wikimedia.org/w/index.php?curid=569240],
|
||||
alt: "ไมโครคอนโทรลเลอร์ 4 ชิ้นที่ขนาดต่างกัน แต่มีช่องให้เห็น EPROM ภายใน",
|
||||
caption: "ไมโครคอนโทรลเลอร์ PIC ต่าง ๆ ที่มี EPROM ภายใน",
|
||||
)
|
||||
|
||||
#v(1em)
|
||||
|
||||
#afigure(
|
||||
image(
|
||||
"Microcontroller/Microcomputer_with_EPROM_(piggyback).jpg",
|
||||
height: 2in,
|
||||
),
|
||||
attr: [Medvedev - Own work, CC BY-SA 3.0,
|
||||
https://commons.wikimedia.org/w/index.php?curid=33161178],
|
||||
alt: "thing",
|
||||
caption: [ไมโครคอนโทรลเลอร์ Piggyback จาก MOSTEK],
|
||||
)
|
||||
|
||||
#iiii ในปี พ.ศ. 2536 การเปิดตัวหน่วยความจำ EEPROM ทำให้ไมโครคอนโทรลเลอร์ (เริ่มต้นด้วย
|
||||
Microchip PIC16C84)
|
||||
สามารถลบข้อมูลด้วยไฟฟ้าได้อย่างรวดเร็วโดยไม่ต้องใช้แพ็คเกจราคาแพงอย่างที่จำเป็นสำหรับ EPROM
|
||||
ซึ่งช่วยให้สามารถสร้างต้นแบบได้อย่างรวดเร็วและตั้งโปรแกรมในระบบได้ (เทคโนโลยี EEPROM
|
||||
มีมาก่อนหน้านี้ แต่ EEPROM รุ่นก่อนหน้านี้มีราคาแพงกว่าและทนทานน้อยกว่า
|
||||
ทำให้ไม่เหมาะสำหรับไมโครคอนโทรลเลอร์ที่ผลิตจำนวนมากในราคาประหยัด) ในปีเดียวกันนั้น Atmel
|
||||
ได้เปิดตัวไมโครคอนโทรลเลอร์ตัวแรกที่ใช้หน่วยความจำ Flash ซึ่งเป็น EEPROM ชนิดพิเศษ บริษัทอื่น ๆ
|
||||
ก็ได้ดำเนินการตามมาอย่างรวดเร็ว โดยมีทั้งหน่วยความจำทั้งสองประเภท
|
||||
|
||||
#iiii ปัจจุบันไมโครคอนโทรลเลอร์มีราคาถูกและหาซื้อได้ง่ายสำหรับผู้ที่ชื่นชอบงานอดิเรก
|
||||
โดยมีชุมชนออนไลน์ขนาดใหญ่ที่ให้ความสนใจกับโปรเซสเซอร์บางประเภท
|
||||
|
||||
=== ปริมาณและค่าใช้จ่าย
|
||||
|
||||
#iiii ในปี 2002 ประมาณ 55% ของ CPU
|
||||
ทั้งหมดที่จำหน่ายในโลกเป็นไมโครคอนโทรลเลอร์และไมโครโปรเซสเซอร์ 8 บิต
|
||||
|
||||
#iiii มีการขายไมโครคอนโทรลเลอร์ 8 บิตมากกว่าสองพันล้านตัวในปี 1997 และจากข้อมูลของ Semico
|
||||
พบว่าไมโครคอนโทรลเลอร์ 8 บิตมากกว่าสี่พันล้านถูกจำหน่ายในปี 2006 ล่าสุด Semico อ้างว่าตลาด MCU
|
||||
เติบโตขึ้น 36.5% ในปี 2010 และ 12% ในปี 2011
|
||||
|
||||
#iiii บ้านทั่วไปในประเทศที่พัฒนาแล้วมีแนวโน้มที่จะมีไมโครโปรเซสเซอร์อเนกประสงค์เพียงสี่ตัว
|
||||
แต่มีไมโครคอนโทรลเลอร์ประมาณสามโหล รถยนต์ระดับกลางทั่วไปมีไมโครคอนโทรลเลอร์ประมาณ 30 ตัว
|
||||
นอกจากนี้ยังสามารถพบได้ในอุปกรณ์ไฟฟ้าหลายชนิด เช่น เครื่องซักผ้า เตาไมโครเวฟ และโทรศัพท์
|
||||
|
||||
#iiii ต้นทุนในการผลิตอาจต่ำกว่า 0.10 เหรียญสหรัฐต่อหน่วย
|
||||
|
||||
#iiii ค่าใช้จ่ายลดลงเมื่อเวลาผ่านไป โดยไมโครคอนโทรลเลอร์ 8 บิตที่ถูกที่สุดมีจำหน่ายในราคาต่ำกว่า
|
||||
0.03 ดอลลาร์สหรัฐฯ ในปี 2018 และไมโครคอนโทรลเลอร์ 32 บิตบางรุ่นมีราคาประมาณ 1
|
||||
ดอลลาร์สหรัฐฯ สำหรับปริมาณที่ใกล้เคียงกัน
|
||||
|
||||
#iiii ในปี 2012 หลังเกิดวิกฤติทั่วโลก ยอดขายลดลงและการฟื้นตัวต่อปีที่เลวร้ายที่สุดเท่าที่เคยมีมา
|
||||
และราคาขายเฉลี่ยเมื่อเทียบเป็นรายปีลดลง 17% ซึ่งถือเป็นการลดลงครั้งใหญ่ที่สุดนับตั้งแต่ทศวรรษ 1980
|
||||
ราคาเฉลี่ยสำหรับไมโครคอนโทรลเลอร์อยู่ที่ 0.88 เหรียญสหรัฐฯ (0.69 เหรียญสหรัฐฯ สำหรับ 4/8 บิต,
|
||||
0.59 เหรียญสหรัฐฯ สำหรับ 16 บิต, 1.76 เหรียญสหรัฐฯ สำหรับ 32 บิต)
|
||||
|
||||
#iiii ในปี 2012 ยอดขายไมโครคอนโทรลเลอร์ 8 บิตทั่วโลกมีมูลค่าประมาณ 4 พันล้านดอลลาร์สหรัฐ
|
||||
ในขณะที่ไมโครคอนโทรลเลอร์ 4 บิตก็มียอดขายที่สำคัญเช่นกัน
|
||||
|
||||
#iiii ในปี 2015 ไมโครคอนโทรลเลอร์ 8 บิตสามารถซื้อได้ในราคา 0.311 ดอลลาร์สหรัฐฯ#jb (1,000
|
||||
หน่วย) 16 บิตราคา 0.385 ดอลลาร์สหรัฐฯ (1,000 หน่วย) และ 32 บิตในราคา 0.378 ดอลลาร์สหรัฐฯ
|
||||
(1,000 หน่วย แต่อยู่ที่ 0.35 ดอลลาร์สหรัฐฯ สำหรับ 5,000)
|
||||
|
||||
#iiii ในปี 2018 ไมโครคอนโทรลเลอร์ 8 บิตสามารถซื้อได้ในราคา 0.03 ดอลลาร์สหรัฐฯ#jb 16
|
||||
บิตในราคา 0.393 ดอลลาร์สหรัฐฯ (1,000 หน่วย แต่ราคา 0.563 ดอลลาร์สหรัฐฯ สำหรับ 100
|
||||
หน่วยหรือ 0.349 ดอลลาร์สหรัฐฯ สำหรับม้วนเต็ม 2,000 หน่วย) และ 32 บิตในราคา 0.503
|
||||
ดอลลาร์#jb สหรัฐฯ (1,000 หน่วย แต่ที่ 0.466 ดอลลาร์สหรัฐสำหรับ 5,000 หน่วย)
|
||||
|
||||
#iiii ในปี 2018 ไมโครคอนโทรลเลอร์ราคาถูกที่สูงกว่าปี 2015 ทั้งหมดมีราคาแพงกว่า
|
||||
(โดยคำนวณอัตราเงินเฟ้อระหว่างราคาปี 2018 ถึง 2015 สำหรับหน่วยเฉพาะเหล่านั้น)
|
||||
โดยไมโครคอนโทรลเลอร์ 8 บิตสามารถซื้อได้ในราคา 0.319 ดอลลาร์สหรัฐฯ (1,000 หน่วย) หรือสูงกว่า
|
||||
2.6%
|
||||
|
||||
#iiii ไมโครคอนโทรลเลอร์ 16 บิตมีราคา 0.464 ดอลลาร์สหรัฐฯ (1,000 หน่วย) หรือ 21% สูงกว่า
|
||||
|
||||
#iiii แบบ 32 บิตในราคา 0.503 ดอลลาร์สหรัฐฯ (1,000 หน่วย แต่อยู่ที่ 0.466 ดอลลาร์สหรัฐฯ
|
||||
สำหรับ 5,000) หรือสูงกว่า 33%
|
||||
|
||||
=== คอมพิวเตอร์ที่เล็กที่สุด
|
||||
|
||||
#iiii เมื่อวันที่ 21 มิถุนายน 2018 มหาวิทยาลัยมิชิแกนได้ประกาศ "คอมพิวเตอร์ที่เล็กที่สุดในโลก"
|
||||
อุปกรณ์ดังกล่าวเป็น "ระบบเซ็นเซอร์ไร้สายและไร้แบตเตอรี่ขนาด 0.04 ลบ.มม. 16 nW
|
||||
พร้อมด้วยโปรเซสเซอร์ Cortex-M0+ ในตัวและการสื่อสารแบบออปติกสำหรับการวัดอุณหภูมิของเซลล์"#jb
|
||||
"วัดด้านข้างเพียง 0.3 มม. ประมาณขนาดเมล็ดข้าว [...] นอกเหนือจาก RAM
|
||||
และเซลล์แสงอาทิตย์แล้ว#jb อุปกรณ์
|
||||
คอมพิวเตอร์รุ่นใหม่ยังมีโปรเซสเซอร์และเครื่องส่งและตัวรับสัญญาณไร้สาย
|
||||
เนื่องจากมีขนาดเล็กเกินไปที่จะมีเสาอากาศวิทยุแบบธรรมดา อุปกรณ์จึงรับและส่งข้อมูลด้วยแสงที่มองเห็นได้
|
||||
สถานีฐานให้แสงสำหรับพลังงานและการเขียนโปรแกรม และรับข้อมูล" อุปกรณ์นี้มีขนาด 1/10 ของขนาดที่
|
||||
IBM อ้างสิทธิ์ก่อนหน้านี้ คอมพิวเตอร์ที่มีขนาดเป็นสถิติโลกเมื่อหลายเดือนก่อนในเดือนมีนาคม 2018 ซึ่ง#jb
|
||||
"เล็กกว่าเม็ดเกลือ" มีทรานซิสเตอร์หนึ่งล้านตัว ต้นทุนการผลิตน้อยกว่า 0.10 ดอลลาร์
|
||||
และเมื่อรวมกับเทคโนโลยีบล็อกเชนแล้ว มีไว้สำหรับการขนส่งและ "จุดยึดเข้ารหัสลับ"
|
||||
ซึ่งเป็นแอปพลิเคชันลายนิ้วมือดิจิทัล
|
||||
|
||||
== ประเภท
|
||||
|
||||
#iii ณ ปี 2008 มีผู้ขายและสถาปัตยกรรมไมโครคอนโทรลเลอร์จำนวนมาก รวมไปถึง:#jb
|
||||
|
||||
#[
|
||||
#set enum(indent: 4.1em)
|
||||
1. หน่วยประมวลผล ARM core โดยเฉพาะคอร์ประเภท ARM Cortex-M
|
||||
2. Microchip Technology Atmel AVR (8 บิต), AVR32 (32 บิต), และ AT91SAM (32 บิต)
|
||||
3. คอร์ M8C ของ Cypress Semiconductor's ที่ถูกใช้ใน Cypress PSoC ของพวกเขา
|
||||
4. Freescale ColdFire (32 บิต) และ S08 (8 บิต)
|
||||
5. Freescale 68HC11 (8 บิต) และอื่น ๆ ที่มีรากฐานมาจากครอบครัว Motorola 6800
|
||||
6. Intel 8051, ซึ่งนอกจาก Intel ก็ถูกผลิตโดย NXP Semiconductors, Infineon, และอื่น ๆ
|
||||
หลายรายการ
|
||||
7. Infineon: 8 บิต XC800, 16 บิต XE166, 32 บิต XMC4000 (ARM based Cortex M4F), 32
|
||||
บิต TriCore, และ 32 บิต Aurix Tricore Bit microcontrollers
|
||||
8. Maxim Integrated MAX32600, MAX32620, MAX32625, MAX32630, MAX32650, MAX32640
|
||||
9. MIPS
|
||||
10. Microchip Technology PIC, (8 บิต PIC16, PIC18, 16 บิต dsPIC33 / PIC24), (32
|
||||
บิต PIC32)
|
||||
11. NXP Semiconductors LPC1000, LPC2000, LPC3000, LPC4000 (32 บิต), LPC900,
|
||||
LPC700 (8 บิต)
|
||||
12. Parallax Propeller
|
||||
13. PowerPC ISE
|
||||
14. Rabbit 2000 (8 บิต)
|
||||
15. Renesas Electronics: RL78 16 บิต MCU; RX 32 บิต MCU; SuperH; V850 32 บิต MCU;
|
||||
H8; R8C 16 บิต MCU
|
||||
16. Silicon Laboratories ไมโครคอนโทรลเลอร์ Pipelined 8 บิต 8051
|
||||
และไมโครคอนโทรลเลอร์แบบ ARM-based 32 บิต สัญญาณผสม
|
||||
17. STMicroelectronics STM8 (8 บิต), ST10 (16 บิต), STM32 (32 บิต), SPC5
|
||||
(automotive 32 บิต)
|
||||
18. Texas Instruments TI MSP430 (16 บิต), MSP432 (32 บิต), C2000 (32 บิต)
|
||||
19. Toshiba TLCS-870 (8 บิต/16 บิต)
|
||||
]
|
||||
|
||||
#iii และยังมีอีกมากมาย โดยบางอย่างนั้นถูกใช้ในแอปพลิเคชันที่เจาะจงมาก
|
||||
หรือเหมือนกับหน่วยประมวลผลเฉพาะแอปพลิเคชันมากกว่าไมโครคอนโทรลเลอร์
|
||||
ตลาดไมโครคอนโทรลเลอร์นั้นกระจัดกระจายเป็นอย่างมาก และมีผู้ขาย เทคโนโลยี และตลาดมากมาย
|
||||
และผู้ขายจำนวนมากขายหลายสถาปัตยกรรม
|
||||
|
||||
== ESP32
|
||||
|
||||
#iii ESP32 คือกลุ่มไมโครคอนโทรลเลอร์ราคาประหยัดและประหยัดพลังงานที่ผสานรวมความสามารถทั้ง
|
||||
Wi-Fi และบลูทูธ ชิปเหล่านี้มีตัวเลือกการประมวลผลที่หลากหลาย รวมถึงไมโครโปรเซสเซอร์ Tensilica
|
||||
Xtensa LX6 ที่มีให้เลือกทั้งแบบ dual-core และ single-core, โปรเซสเซอร์#jb Xtensa LX7
|
||||
dual-core หรือไมโครโปรเซสเซอร์ RISC-V แบบ single-core นอกจากนี้ ESP32
|
||||
ยังรวมส่วนประกอบที่จำเป็นสำหรับการสื่อสารข้อมูลไร้สาย เช่น สวิตช์เสาอากาศในตัว บาลัน RF
|
||||
เครื่องขยายกำลัง เครื่องรับสัญญาณรบกวนต่ำ ตัวกรอง และโมดูลการจัดการพลังงาน
|
||||
|
||||
#v(0.5em)
|
||||
|
||||
#afigure(
|
||||
image("Microcontroller/ESP32-C3_RISC-V_NodeMCU_board.jpg", width: 1.5in),
|
||||
alt: "บอร์ดสีดำ มีพิน GPIO ด้านข้างและมีชิพอยู่บริเวณด้านบนบอร์ด",
|
||||
attr: [Popolon, CC BY-SA 4.0,
|
||||
https://commons.wikimedia.org/w/index.php?curid=112634884],
|
||||
caption: [บอร์ด NodeMCU ที่มี ESP32-C3-32S],
|
||||
)
|
||||
|
||||
#iii โดยทั่วไปแล้ว ESP32
|
||||
จะถูกฝังอยู่บนแผงวงจรพิมพ์เฉพาะอุปกรณ์หรือนำเสนอเป็นส่วนหนึ่งของชุดการพัฒนาที่มีพินและตัวเชื่อมต่อ GPIO
|
||||
ที่หลากหลาย โดยมีการกำหนดค่าที่แตกต่างกันไปตามรุ่นและผู้ผลิต ESP32 ได้รับการออกแบบโดย Espressif
|
||||
Systems และผลิตโดย TSMC โดยใช้กระบวนการ 40 นาโนเมตร มันเป็นผู้สืบทอดของไมโครคอนโทรลเลอร์
|
||||
ESP8266
|
||||
|
||||
=== Espressif Systems
|
||||
|
||||
#iiii บริษัท Espressif Systems (Shanghai) จำกัด (เอสเพรสซิฟ)
|
||||
เป็นบริษัทเซมิคอนดักเตอร์สัญชาติจีนที่จดทะเบียนในตลาดหลักทรัพย์ มีสำนักงานใหญ่ตั้งอยู่ที่เซี่ยงไฮ้
|
||||
บริษัทมุ่งเน้นการพัฒนาและจำหน่ายชิปและโมดูลสื่อสารไมโครคอนโทรลเลอร์ไร้สายที่ใช้ใน Internet of
|
||||
things (IoT)
|
||||
|
||||
#iiii ผลิตภัณฑ์เซมิคอนดักเตอร์ที่เป็นที่รู้จักมากที่สุดสองอย่างของ Espressif คือ ESP8266 และ ESP32
|
||||
ซึ่งเป็นรุ่นต่อจาก ESP8266 ผลิตภัณฑ์เหล่านี้ถูกนำไปใช้ในผลิตภัณฑ์ต่างๆ เช่น เครื่องชงกาแฟและหลอดไฟ
|
||||
รวมถึงผู้ให้บริการโซลูชันเมืองอัจฉริยะและระบบอัตโนมัติ นอกจากนี้ยังถูกใช้โดยผู้ที่ชื่นชอบงาน DIY
|
||||
ด้านเทคโนโลยีอีกด้วย
|
||||
|
||||
== ตารางพาร์ทิชัน (Partition Table)
|
||||
|
||||
#i ตารางพาร์ทิชันคือสิ่งที่กำหนดการจัดการรูปแบบหน่วยความจำแฟลชและข้อมูลต่าง ๆ
|
||||
#iii ตารางพาร์ทิชันคือสิ่งที่กำหนดการจัดการรูปแบบหน่วยความจำแฟลชและข้อมูลต่าง ๆ
|
||||
จะถูกเก็บไว้ในแต่ละพาร์ทิชัน
|
||||
โดยผู้พัฒนาสามารถใช้รูปแบบตารางพาร์ทิชันที่ถูกกำหนดมาไว้แล้วหรือสามารถกำหนดรูปแบบตารางพาร์ทิชันเองก็ได้
|
||||
|
||||
#i โดยตารางพาร์ทัชันที่ถูกใช้ในโครงงานนี้มีรูปแบบดังนี้
|
||||
โดยตารางพาร์ทัชันที่ถูกใช้ในโครงงานนี้มีรูปแบบดังนี้
|
||||
|
||||
#let partition-table = csv("PartitionTable.csv")
|
||||
|
||||
#table(
|
||||
#figure(
|
||||
table(
|
||||
columns: 6,
|
||||
align: left,
|
||||
table.header([Name], [Type], [SubType], [Offset], [Size], [Flags]),
|
||||
..partition-table.flatten().slice(6),
|
||||
),
|
||||
caption: [รายการพาร์ทิชัน],
|
||||
)
|
||||
|
||||
ซึ่งคือตารางค่าเริ่มต้นของ ESP32 ใน Arduino platform
|
||||
อย่างไรก็ตามมีการเปลี่ยนแปลงระบบเก็บไฟล์จาก SPIFFS เป็น LittleFS โดยที่:
|
||||
#iii ซึ่งคือตารางค่าเริ่มต้นของ ESP32 ใน Arduino platform
|
||||
อย่างไรก็ตามมีการเปลี่ยนแปลงระบบเก็บไฟล์จาก SPIFFS เป็น LittleFS โดยที่
|
||||
|
||||
+ *Name:* ชื่อของพาร์ทิชัน ห้ามซ้ำกัน ชื่อนั้นไม่สำคัญต่อระบบและต้องขนาดไม่เกิน 16 ตัวอักษร
|
||||
(ไม่มีอักขระพิเศษ)
|
||||
+ *Type:* ประเภทของพาร์ทัชัน สามารถเป็น `data` หรือ `app` ได้
|
||||
- `app` คือพาร์ทิชันที่ใช้ในการเก็บแอพลิเคชัน
|
||||
- `data` คือพาร์ทิชันที่ใช้ในการเก็บข้อมูลทั่วไป
|
||||
+ *SubType:* ประเภทย่อย ระบุการใช้งานของพาร์ทิชัน `app` และ `data`
|
||||
- `data`
|
||||
- `ota`: พาร์ทัชันเก็บข้อมูล OTA (สำหรับการอัพเดททางอากาศ, Over-the-air update)
|
||||
=== Name
|
||||
|
||||
#iiii Name คือ ชื่อของพาร์ทิชัน ห้ามซ้ำกัน ชื่อนั้นไม่สำคัญต่อระบบและต้องขนาดไม่เกิน 16 ตัวอักษร
|
||||
(ไม่มีอักขระพิเศษ)
|
||||
|
||||
=== Type
|
||||
|
||||
#iiii Type คือ ประเภทของพาร์ทิชัน สามารถเป็น data หรือ app ได้
|
||||
|
||||
#[
|
||||
#set enum(indent: 7.55em)
|
||||
+ app คือพาร์ทิชันที่ใช้ในการเก็บแอปพลิเคชัน
|
||||
+ data คือพาร์ทิชันที่ใช้ในการเก็บข้อมูลทั่วไป
|
||||
]
|
||||
|
||||
=== SubType
|
||||
|
||||
#iiii SubType คือ ประเภทย่อย ระบุการใช้งานของพาร์ทิชัน data และ app
|
||||
|
||||
#[
|
||||
#set enum(indent: 7.55em)
|
||||
1. data
|
||||
#listy(
|
||||
indent: 8.8em,
|
||||
numbering: thai-numbering,
|
||||
[ota คือ พาร์ทัชันเก็บข้อมูล OTA (สำหรับการอัพเดททางอากาศ, Over-the-air update)
|
||||
โดยหากไม่ใช้งาน OTA สามารถนำออกได้ โดยขนาดของพาร์ทิชันนี้ควรจะมีขนาดที่แน่นอนอยู่ที่ 8 KiB
|
||||
(0x2000 ไบต์)
|
||||
- `nvs`: พาร์ทิชันเก็บข้อมูลทั่วไปเช่น ข้อมูล Wi-Fi, ข้อมูลการสอบเทียบ PHY ของอุปกรณ์,
|
||||
(0x2000 ไบต์)],
|
||||
[nvs คือ พาร์ทิชันเก็บข้อมูลทั่วไปเช่น ข้อมูล Wi-Fi, ข้อมูลการสอบเทียบ PHY ของอุปกรณ์,
|
||||
และข้อมูลอื่น ๆ ที่ต้องถูกเก็บบนหน่วยความจำถาวร (Non-volatile memory)
|
||||
โดยพาร์ทิชันประเภทนี้เหมาะสมสำหรับการเก็บข้อมูลการตั้งค่าเล็กน้อย ใบรองรับคลาวด์ ฯลฯ
|
||||
และการใช้งาน NVS อีกอย่างคือการเก็บข้อมูลที่ละเอียดอ่อน เนื่องจาก NVS รองรับการเข้ารหัส
|
||||
และเป็นสิ่งที่แนะนำอย่างมากที่จะมีพาร์ทิชัน NVS ขนาดขั้นต่ำ 12 KiB (0x3000 ไบต์)
|
||||
และหากจำเป็น คุณสามารถขยายขนาดเพิ่มได้ โดยขนาดที่แนะนำนั้นอยู่ระหว่าง 12 KiB และ 64
|
||||
KiB ถึงแม้ว่าคุณจะสามารถขยายให้มันใหญ่กว่านี้ได้ การใช้งานระบบไฟล์เช่น FAT หรือ SPIFFS
|
||||
นั้นจะเหมาะสมสำหรับข้อมูลที่ใหญ่กว่า
|
||||
- `coredump`: ประเภทพาร์ทิชันย่อยนี้มีหน้าที่ในการเก็บข้อมูล core dump บนหน่วยความจำแฟลช
|
||||
นั้นจะเหมาะสมสำหรับข้อมูลที่ใหญ่กว่า],
|
||||
[coredump คือ ประเภทพาร์ทิชันย่อยนี้มีหน้าที่ในการเก็บข้อมูล core dump บนหน่วยความจำแฟลช
|
||||
โดย core dump
|
||||
นั้นคือข้อมูลที่ถูกใช้งานสำหรับการตรวจสอบข้อผิด-พลาดร้ายแรงเช่นการแครชและแพนิค
|
||||
โดยฟังก์ชันนี้จะต้องถูกเปิดในการตั้งค่าโปรเจกต์และตั้งที่หมายในการแฟลช
|
||||
และพาร์ทิชันนี้มีขนาดที่แนะนำอยู่ที่ 64 KiB (0x10000)
|
||||
- `nvs_keys`: พาร์ทิชันที่เป็นประเภทย่อยนี้เก็บคีย์การเข้ารหัสของพาร์ทัชัน NVS
|
||||
เมื่อการเข้ารหัสถูกใช้งาน โดยมีขนาดอยู่ที่ 4 KiB (0x1000)
|
||||
- `fat`: กำหนดพาร์ทิชันสำหรับระบบไฟล์ FAT โดยที่จะเหมาะสมสำหรับข้อมูลใหญ่ ๆ
|
||||
และพาร์ทิชันนี้มีขนาดที่แนะนำอยู่ที่ 64 KiB (0x10000)],
|
||||
[nvs_keys คือ พาร์ทิชันที่เป็นประเภทย่อยนี้เก็บคีย์การเข้ารหัสของพาร์ทัชัน NVS
|
||||
เมื่อการเข้ารหัสถูกใช้งาน โดยมีขนาดอยู่ที่ 4 KiB (0x1000)],
|
||||
[fat คือ กำหนดพาร์ทิชันสำหรับระบบไฟล์ FAT โดยที่จะเหมาะสมสำหรับข้อมูลใหญ่ ๆ
|
||||
และหากข้อมูลนั้นถูกเปลี่ยนแปลงบ่อย โดยระบบไฟล์ FAT สามารถใช้ฟีเจอร์ wear leveling
|
||||
และการเข้ารหัสได้
|
||||
- `spiffs`: กำหนดพาร์ทิชันสำหรับระบบไฟล์ SPIFFS เหมาะสำหรับไฟล์ใหญ่เช่นกันและรองรับ
|
||||
wear leveling อย่างไรก็ตาม ระบบไฟล์นี้ไม่รองรับการเข้ารหัส
|
||||
- `app`
|
||||
- `factory`: พาร์ทิชันเก็บแอพลิเคชันเริ่มต้น
|
||||
โปรแกรมบูตโหลดเดอร์จะเลือกพาร์ทิชันนี้เป็นแอพลิเคชันเริ่มต้นหากไม่มีพาร์ทิชัน OTA หรือพาร์ทิชัน
|
||||
OTA นั้นว่างเปล่า หากมีการใช้พาร์ทิชัน OTA พาร์ทิชัน `ota_0`
|
||||
สามารถถูกใช้เป็นแอพลิเคชันเริ่มต้นได้และพาร์ทิชัน `factory` สามารถถูกนำออกได้
|
||||
- `ota_0` ถึง `ota_15`: พาร์ทิชัน ota_x นั้นถูกใช้สำหรับอัพเดท OTA โดยฟีเจอร์ OTA
|
||||
และการเข้ารหัสได้],
|
||||
[spiffs คือ กำหนดพาร์ทิชันสำหรับระบบไฟล์ SPIFFS เหมาะสำหรับไฟล์ใหญ่เช่นกันและรองรับ wear
|
||||
leveling อย่างไรก็ตาม ระบบไฟล์นี้ไม่รองรับการเข้ารหัส],
|
||||
)
|
||||
2. app
|
||||
#listy(
|
||||
indent: 8.8em,
|
||||
numbering: thai-numbering,
|
||||
[factory คือ พาร์ทิชันเก็บแอปพลิเคชันเริ่มต้น
|
||||
โปรแกรมบูตโหลดเดอร์จะเลือกพาร์ทิชันนี้เป็นแอปพลิเคชันเริ่มต้นหากไม่มีพาร์ทิชัน OTA หรือพาร์ทิชัน
|
||||
OTA นั้นว่างเปล่า หากมีการใช้พาร์ทิชัน OTA พาร์ทิชัน ota_0
|
||||
สามารถถูกใช้เป็นแอปพลิเคชันเริ่มต้นได้และพาร์ทิชัน factory สามารถถูกนำออกได้],
|
||||
[ota_0 ถึง ota_15 คือ พาร์ทิชัน ota_x นั้นถูกใช้สำหรับอัพเดท OTA โดยฟีเจอร์ OTA
|
||||
นั้นจำเป็นต้องใช้พาร์ทิชัน OTA อย่างน้อย 2 พาร์ทิชัน (โดยปกติคือ ota_0 และ ota_1)
|
||||
และจำเป็นต้องใช้พาร์ทิชัน ota ด้วยเช่นกันในการเก็บข้อมูลเกี่ยวกับ OTA โดยสามารถมีพาร์ทิชัน
|
||||
OTA ได้สูงสุด 16 พาร์ทิชัน แต่ 2 พาร์ทิชันคือจำนวนขั้นต่ำที่ต้องใช้สำหรับฟีเจอร์ OTA แบบเบสิค
|
||||
- `test`: ใช้สำหรับการทดสอบในโรงงาน
|
||||
+ *Offset:* กำหนดพื้นที่ที่พาร์ทิชันนั้น ๆ เริ่มต้น โดย Offset นั้นถูกกำหนดโดยการรวมค่า Offset
|
||||
และขนาดของพาร์ทิชันก่อนหน้า \
|
||||
*หมายเหตุ:* Offset จะต้องเป็นทวีคูณของ 4 KiB (0x1000)
|
||||
และพาร์ทิชันแอพจะต้องจัดตำแหน่งให้มีขนาด 64 KiB (0x10000) โดยหากปล่อยให้ว่าง ค่า Offset
|
||||
จะถูกคำนวนโดยอัตโนมัติตามตำแหน่งท้ายของพาร์ทิชันก่อนหน้า รวมถึงการจัดตำแหน่งใด ๆ ที่จำเป็น
|
||||
อย่างไรก็ตาม Offset ของพาร์ทิชันแรกนั้นจะต้องเป็น *0x9000* และ *0x10000*
|
||||
สำหรับพาร์ทิชันแอพลิเคชันแรก
|
||||
+ *Size:* ขนาดของพาร์ทิชัน โดยค่านี้สามารถเป็นเลขทศนิยม, ตัวเลข Hex (นำหน้าด้วย `0x`),
|
||||
หรือใช้ตัวอักษรต่อท้ายเพื่อบ่งบอกหน่วย K (กิโล) หรือ M (เมกา) เช่น 4096 = 4K = 0x1000
|
||||
+ *Flags:* ในปัจจุบันคอลัมน์นี้ใช้เพียงแค่เพื่อบ่งบอกว่าพาร์ทิชันนั้น ๆ ถูกเข้ารหัสหรือไม่
|
||||
OTA ได้สูงสุด 16 พาร์ทิชัน แต่ 2 พาร์ทิชันคือจำนวนขั้นต่ำที่ต้องใช้สำหรับฟีเจอร์ OTA แบบเบสิค],
|
||||
[test คือ ใช้สำหรับการทดสอบในโรงงาน],
|
||||
)
|
||||
]
|
||||
|
||||
== LittleFS
|
||||
#i LittleFS คือระบบไฟล์ขนาดเล็กที่ปลอดภัยต่อความล้มเหลวที่ออกแบบมาสำหรับ#jb
|
||||
=== Offset
|
||||
|
||||
#iiii Offset คือ กำหนดพื้นที่ที่พาร์ทิชันนั้น ๆ เริ่มต้น โดย Offset นั้นถูกกำหนดโดยการรวมค่า Offset
|
||||
และขนาดของพาร์ทิชันก่อนหน้า 0 อย่างไรก็ตาม Offset จะต้องเป็นทวีคูณของ 4 KiB (0x1000)
|
||||
และพาร์ทิชันแอพจะต้องจัดตำแหน่งให้มีขนาด 64 KiB (0x10000) โดยหากปล่อยให้ว่าง ค่า Offset
|
||||
จะถูกคำนวนโดยอัตโนมัติตามตำแหน่งท้ายของพาร์ทิชันก่อนหน้า รวมถึงการจัดตำแหน่งใด ๆ ที่จำเป็น
|
||||
อย่างไรก็ตาม Offset ของพาร์ทิชันแรกนั้นจะต้องเป็น 0x9000 และ 0x10000
|
||||
สำหรับพาร์ทิชันแอปพลิเคชันแรก
|
||||
|
||||
=== Size
|
||||
|
||||
#iiii Size คือ ขนาดของพาร์ทิชัน โดยค่านี้สามารถเป็นเลขทศนิยม, ตัวเลข Hex (นำหน้าด้วย 0x),
|
||||
หรือใช้ตัวอักษรต่อท้ายเพื่อบ่งบอกหน่วย K (กิโล) หรือ M (เมกา) เช่น 4096 = 4K = 0x1000
|
||||
|
||||
=== Flags
|
||||
|
||||
#iiii Flags คือ ในปัจจุบันคอลัมน์นี้ใช้เพียงแค่เพื่อบ่งบอกว่าพาร์ทิชันนั้น ๆ ถูกเข้ารหัสหรือไม่
|
||||
|
||||
|
||||
== littlefs
|
||||
#iii littlefs คือระบบไฟล์ขนาดเล็กที่ปลอดภัยต่อความล้มเหลวที่ออกแบบมาสำหรับ#jb
|
||||
ไมโครคอนโทรลเลอร์
|
||||
|
||||
#show raw: set par(leading: 0.5em)
|
||||
|
||||
```
|
||||
| | | .---._____
|
||||
.-----. | |
|
||||
--|o |---| littlefs |
|
||||
--| |---| |
|
||||
'-----' '----------'
|
||||
| | |
|
||||
```
|
||||
|
||||
*ความยืดหยุ่นในการป้องกันการสูญเสียพลังงาน* littlefs ออกแบบมาเพื่อรับมือกับปัญหาไฟฟ้าดับแบบสุ่ม
|
||||
#iii ความยืดหยุ่นในการป้องกันการสูญเสียพลังงาน littlefs ออกแบบมาเพื่อรับมือกับปัญหาไฟฟ้าดับแบบสุ่ม
|
||||
การดำเนินการไฟล์ทั้งหมดมีการรับประกันการคัดลอกข้อมูลเมื่อเขียนข้อมูล (copy-on-write) ที่แข็งแกร่ง
|
||||
และหากไฟฟ้าดับ ระบบไฟล์จะกลับสู่สถานะปกติล่าสุดที่ทราบ
|
||||
|
||||
*การปรับระดับการสึกหรอแบบไดนามิก* littlefs ออกแบบมาเพื่อแฟลชโดยเฉพาะ
|
||||
#iii การปรับระดับการสึกหรอแบบไดนามิก littlefs ออกแบบมาเพื่อแฟลชโดยเฉพาะ
|
||||
และมอบการปรับระดับการสึกหรอบนบล็อกแบบไดนามิก นอกจากนี้ littlefs
|
||||
ยังสามารถตรวจจับบล็อกเสียและแก้ไขปัญหาได้
|
||||
|
||||
*RAM/ROM แบบมีขอบเขต* littlefs ออกแบบมาเพื่อทำงานกับหน่วยความจำขนาดเล็ก การใช้งาน#jb
|
||||
RAM ถูกจำกัดอย่างเข้มงวด ซึ่งหมายความว่าการใช้ RAM จะไม่เปลี่ยนแปลงเมื่อระบบไฟล์เติบโตขึ้น#jb
|
||||
#iii RAM/ROM แบบมีขอบเขต littlefs ออกแบบมาเพื่อทำงานกับหน่วยความจำขนาดเล็ก#jb การใช้งาน
|
||||
RAM ถูกจำกัดอย่างเข้มงวด ซึ่งหมายความว่าการใช้ RAM จะไม่เปลี่ยนแปลงเมื่อระบบไฟล์เติบโตขึ้น
|
||||
ระบบไฟล์ไม่มีการเรียกซ้ำแบบไม่มีขอบเขต
|
||||
และหน่วยความจำแบบไดนามิกถูกจำกัดให้อยู่ในบัฟเฟอร์ที่กำหนดค่าได้ซึ่งสามารถจัดเตรียมแบบคงที่ได้
|
||||
|
||||
== ออกแบบ
|
||||
|
||||
#i ในระดับสูง littlefs
|
||||
#iii ในระดับสูง littlefs
|
||||
เป็นระบบไฟล์แบบบล็อกที่ใช้ไฟล์บันทึกขนาดเล็กในการจัดเก็บข้อมูลเมตาและโครงสร้าง copy-on-write
|
||||
(COW) ขนาดใหญ่ในการจัดเก็บข้อมูลไฟล์
|
||||
|
||||
#i ใน littlefs ส่วนผสมเหล่านี้ก่อตัวเป็นเค้กสองชั้น โดยที่ท่อนไม้ขนาดเล็ก (เรียกว่าคู่เมตาเดตา)#jb
|
||||
จะให้การอัปเดตเมตาเดตาอย่างรวดเร็วในทุกที่ในที่เก็บข้อมูล ในขณะที่โครงสร้าง COW
|
||||
จะจัดเก็บข้อมูลไฟล์อย่างกะทัดรัดและไม่มีค่าใช้จ่ายในการขยายการสึกหรอใด ๆ
|
||||
#iii ใน littlefs ส่วนผสมเหล่านี้ก่อตัวเป็นเค้กสองชั้น โดยที่ท่อนไม้ขนาดเล็ก
|
||||
(เรียกว่าคู่เมตาเดตา)#jb จะให้การอัปเดตเมตาเดตาอย่างรวดเร็วในทุกที่ในที่เก็บข้อมูล
|
||||
ในขณะที่โครงสร้าง COW จะจัดเก็บข้อมูลไฟล์อย่างกะทัดรัดและไม่มีค่าใช้จ่ายในการขยายการสึกหรอใด ๆ
|
||||
|
||||
#i โครงสร้างข้อมูลทั้งสองนี้สร้างขึ้นจากบล็อก ซึ่งถูกป้อนโดยตัวจัดสรรบล็อกร่วม
|
||||
โดยการจำกัดจำนวนการลบข้อมูลที่อนุญาตบนบล็อกต่อการจัดสรรแต่ละครั้ง
|
||||
ตัวจัดสรรจะปรับระดับการสึกหรอแบบไดนามิกทั่วทั้งระบบไฟล์
|
||||
#iii โครงสร้างข้อมูลทั้งสองนี้สร้างขึ้นจากบล็อก ซึ่งถูกป้อนโดยตัวจัดสรรบล็อกร่วม
|
||||
โดยการจำกัดจำนวนการลบข้อมูลที่อนุญาตบนบล็อกต่อการจัดสรรแต่ละครั้ง ตัวจัดสรรจะปรับระดับการ#jb
|
||||
สึกหรอแบบไดนามิกทั่วทั้งระบบไฟล์
|
||||
|
||||
```
|
||||
#show raw: set par(leading: 0.35em)
|
||||
#show raw: set text(size: 6pt)
|
||||
|
||||
#afigure(
|
||||
```
|
||||
root
|
||||
.--------.--------.
|
||||
| A'| B'| |
|
||||
@@ -156,11 +392,11 @@ RAM ถูกจำกัดอย่างเข้มงวด ซึ่งห
|
||||
'--------'--------' '--------'--------'
|
||||
.-' '--. | '------------------.
|
||||
v v .-' v
|
||||
.--------. .--------. v .--------.
|
||||
| C | | D | .--------. write | new E |
|
||||
| | | | | E | ==> | |
|
||||
| | | | | | | |
|
||||
'--------' '--------' | | '--------'
|
||||
.--------. .--------. v .--------.
|
||||
| C | | D | .--------. write | new E |
|
||||
| | | | | E | ==> | |
|
||||
| | | | | | | |
|
||||
'--------' '--------' | | '--------'
|
||||
'--------' .-' |
|
||||
.-' '-. .-------------|------'
|
||||
v v v v
|
||||
@@ -169,4 +405,9 @@ RAM ถูกจำกัดอย่างเข้มงวด ซึ่งห
|
||||
| | | | | |
|
||||
| | | | | |
|
||||
'--------' '--------' '--------'
|
||||
```
|
||||
```,
|
||||
kind: image,
|
||||
attr: [เจ้าของ LittleFS (ภายใต้สัญญาอนุญาต BSD-3-Clause)],
|
||||
supplement: "รูปที่",
|
||||
caption: [แสดงการทำงานเบื้องต้นของ LittleFS],
|
||||
)
|
||||
|
||||
|
After Width: | Height: | Size: 723 KiB |
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 1.0 MiB |
@@ -2,37 +2,91 @@
|
||||
|
||||
= การสื่อสารสนามใกล้ (Near-field communication; NFC)
|
||||
|
||||
#i การสื่อสารแบบใกล้สนาม (NFC) คือชุดโปรโตคอลการสื่อสารที่ทำให้สามารถสื่อสารระหว่างอุปกรณ์อิเล็กทรอนิกส์สองเครื่องในระยะทาง 4 ซม. (#math.equation(alt: "1 เศษ 1 ส่วน 2", $1 1/2$) นิ้ว) หรือน้อยกว่า NFC นำเสนอการเชื่อมต่อความเร็วต่ำผ่านการตั้งค่าที่ง่ายดายซึ่งสามารถใช้สำหรับการบูตสแตรปของการเชื่อมต่อไร้สายที่สามารถใช้งานได้เช่นเดียวกับเทคโนโลยีการ์ดระยะใกล้อื่นๆ NFC มีพื้นฐานมาจากการเชื่อมต่อแบบเหนี่ยวนำ ระหว่างขดลวดแม่เหล็กไฟฟ้าสองอันบนอุปกรณ์ที่รองรับ NFC เช่นสมาร์ทโฟนการสื่อสาร NFC ในทิศทางเดียวหรือทั้งสองทิศทางใช้ความถี่ 13.56 MHz ในย่านความถี่วิทยุ ISM ที่ไม่มีใบอนุญาต ซึ่งใช้กันทั่วโลก สอดคล้องกับมาตรฐานอินเทอร์เฟซทางอากาศ ISO/IEC 18000-3 ที่อัตราข้อมูลตั้งแต่ 106 ถึง 848 กิโลบิต/วินาที
|
||||
#h(1.7em) การสื่อสารแบบใกล้สนาม (NFC)
|
||||
คือชุดโปรโตคอลการสื่อสารที่ทำให้สามารถสื่อสารระหว่างอุปกรณ์อิเล็กทรอนิกส์สองเครื่องในระยะทาง 4 ซม.
|
||||
(#math.equation(alt: "1 เศษ 1 ส่วน 2", $1 1/2$) นิ้ว) หรือน้อยกว่า NFC
|
||||
นำเสนอการเชื่อมต่อความเร็วต่ำผ่านการตั้งค่าที่ง่ายดายซึ่งสามารถใช้สำหรับการบูตสแตรปของการเชื่อมต่อไร้สายที่สามารถใช้งานได้เช่นเดียวกับเทคโนโลยีการ์ดระยะใกล้อื่นๆ
|
||||
NFC มีพื้นฐานมาจากการเชื่อมต่อแบบเหนี่ยวนำ ระหว่างขดลวดแม่เหล็กไฟฟ้าสองอันบนอุปกรณ์ที่รองรับ NFC
|
||||
เช่นสมาร์ทโฟนการสื่อสาร NFC ในทิศทางเดียวหรือทั้งสองทิศทางใช้ความถี่ 13.56 MHz ในย่านความถี่วิทยุ
|
||||
ISM ที่ไม่มีใบอนุญาต ซึ่งใช้กันทั่วโลก สอดคล้องกับมาตรฐานอินเทอร์เฟซทางอากาศ ISO/IEC 18000-3
|
||||
ที่อัตราข้อมูลตั้งแต่ 106 ถึง 848 กิโลบิต/วินาที
|
||||
|
||||
#i ฟอรัม NFC ได้ช่วยกำหนดและส่งเสริมเทคโนโลยีโดยกำหนดมาตรฐานสำหรับการรับรองการปฏิบัติตามข้อกำหนดของอุปกรณ์การสื่อสารที่ปลอดภัยสามารถทำได้โดยใช้ขั้นตอนวิธีการเข้ารหัสเช่นเดียวกับที่ใช้กับบัตรเครดิตและหากตรงตามเกณฑ์สำหรับการพิจารณาให้เป็นเครือข่ายพื้นที่ส่วนบุคคล
|
||||
#h(1.7em) ฟอรัม NFC
|
||||
ได้ช่วยกำหนดและส่งเสริมเทคโนโลยีโดยกำหนดมาตรฐานสำหรับการรับรองการปฏิบัติตามข้อกำหนดของอุปกรณ์การสื่อสารที่ปลอดภัยสามารถทำได้โดยใช้ขั้นตอนวิธีการเข้ารหัสเช่นเดียวกับที่ใช้กับบัตรเครดิตและหากตรงตามเกณฑ์สำหรับการพิจารณาให้เป็นเครือข่ายพื้นที่ส่วนบุคคล
|
||||
|
||||
== มาตราฐาน NFC
|
||||
|
||||
#i มาตรฐาน NFC ครอบคลุมโปรโตคอลการสื่อสารและรูปแบบการแลกเปลี่ยนข้อมูล และอิงตามมาตรฐานการระบุด้วยคลื่นความถี่วิทยุ (RFID) ที่มีอยู่ รวมถึง ISO/IEC 14443 และ FeliCa มาตรฐานเหล่านี้รวมถึง ISO/IEC 18092 และมาตรฐานที่กำหนดโดย NFC Forum นอกจาก NFC Forum แล้วกลุ่ม GSMA ยังได้กำหนดแพลตฟอร์มสำหรับการปรับใช้มาตรฐาน NFC ของ GSMA ภายในโทรศัพท์มือถือ ความพยายามของ GSMA ได้แก่ Trusted Services Manager, Single Wire Protocol, การทดสอบ/การรับรอง และองค์ประกอบความปลอดภัยอุปกรณ์พกพาที่เปิดใช้งาน NFC สามารถมาพร้อมกับซอฟต์แวร์แอปพลิเคชันเช่น เพื่ออ่านแท็กอิเล็กทรอนิกส์หรือชำระเงินเมื่อเชื่อมต่อกับระบบที่รองรับ NFC สิ่งเหล่านี้เป็นมาตรฐานของโปรโตคอล NFC แทนที่เทคโนโลยีที่เป็นกรรมสิทธิ์ที่ใช้ในระบบก่อนหน้านี้
|
||||
#h(4.2em) มาตรฐาน NFC ครอบคลุมโปรโตคอลการสื่อสารและรูปแบบการแลกเปลี่ยนข้อมูล
|
||||
และอิงตามมาตรฐานการระบุด้วยคลื่นความถี่วิทยุ (RFID) ที่มีอยู่ รวมถึง ISO/IEC 14443 และ FeliCa
|
||||
มาตรฐานเหล่านี้รวมถึง ISO/IEC 18092 และมาตรฐานที่กำหนดโดย NFC Forum นอกจาก NFC Forum
|
||||
แล้วกลุ่ม GSMA ยังได้กำหนดแพลตฟอร์มสำหรับการปรับใช้มาตรฐาน NFC ของ GSMA ภายในโทรศัพท์มือถือ
|
||||
ความพยายามของ GSMA ได้แก่ Trusted Services Manager, Single Wire Protocol,
|
||||
การทดสอบ/การรับรอง และองค์ประกอบความปลอดภัยอุปกรณ์พกพาที่เปิดใช้งาน NFC
|
||||
สามารถมาพร้อมกับซอฟต์แวร์แอปพลิเคชันเช่น
|
||||
เพื่ออ่านแท็กอิเล็กทรอนิกส์หรือชำระเงินเมื่อเชื่อมต่อกับระบบที่รองรับ NFC
|
||||
สิ่งเหล่านี้เป็นมาตรฐานของโปรโตคอล NFC แทนที่เทคโนโลยีที่เป็นกรรมสิทธิ์ที่ใช้ในระบบก่อนหน้านี้
|
||||
|
||||
#i โปรแกรมอนุญาตสิทธิ์สิทธิบัตรสำหรับ NFC กำลังอยู่ระหว่างการใช้งานโดย France Brevets ซึ่งเป็นกองทุนสิทธิบัตรที่จัดตั้งขึ้นในปี 2011 โปรแกรมนี้อยู่ระหว่างการพัฒนาโดย Via Licensing Corporation ซึ่งเป็นบริษัทสาขาอิสระของ Dolby Laboratories และยุติลงในเดือนพฤษภาคม 2012 ไลบรารี NFC แบบโอเพนซอร์สและอิสระต่อแพลตฟอร์ม libnfc มีให้บริการภายใต้ใบอนุญาตสาธารณะทั่วไปแบบผ่อนปรนของ GNU
|
||||
#h(4.2em) โปรแกรมอนุญาตสิทธิ์สิทธิบัตรสำหรับ NFC กำลังอยู่ระหว่างการใช้งานโดย France Brevets
|
||||
ซึ่งเป็นกองทุนสิทธิบัตรที่จัดตั้งขึ้นในปี 2011 โปรแกรมนี้อยู่ระหว่างการพัฒนาโดย Via Licensing
|
||||
Corporation ซึ่งเป็นบริษัทสาขาอิสระของ Dolby Laboratories และยุติลงในเดือน#jb พฤษภาคม
|
||||
2012 ไลบรารี NFC แบบโอเพนซอร์สและอิสระต่อแพลตฟอร์ม libnfc มีให้บริการภายใต้ใบอนุญาต GNU
|
||||
Lesser General Public License (LGPL)
|
||||
|
||||
#i แอปพลิเคชันปัจจุบันและที่คาดว่าจะมีในอนาคต ได้แก่ ธุรกรรมแบบไร้สัมผัส การแลกเปลี่ยนข้อมูล และการตั้งค่าการสื่อสารที่ซับซ้อนมากขึ้น เช่น Wi-Fi ที่ง่าย ขึ้นนอกจากนี้เมื่ออุปกรณ์ที่เชื่อมต่อเครื่องหนึ่งมีการเชื่อมต่ออินเทอร์เน็ตอีกเครื่องหนึ่งก็สามารถแลกเปลี่ยนข้อมูลกับบริการออนไลน์ได้
|
||||
#h(4.2em) แอปพลิเคชันปัจจุบันและที่คาดว่าจะมีในอนาคต ได้แก่ ธุรกรรมแบบไร้สัมผัส การแลกเปลี่ยนข้อมูล
|
||||
และการตั้งค่าการสื่อสารที่ซับซ้อนมากขึ้น เช่น Wi-Fi ที่ง่าย
|
||||
ขึ้นนอกจากนี้เมื่ออุปกรณ์ที่เชื่อมต่อเครื่องหนึ่งมีการเชื่อมต่ออินเทอร์เน็ตอีกเครื่องหนึ่งก็สามารถแลกเปลี่ยนข้อมูลกับบริการออนไลน์ได้
|
||||
|
||||
== ออกแบบ
|
||||
|
||||
#i NFC เป็นชุดเทคโนโลยีไร้สายระยะสั้น โดยทั่วไปต้องมีระยะห่าง 10 ซม. (#math.equation(alt: "3 เศษ 7 ส่วน 8", $3 7/8$) นิ้ว) หรือน้อยกว่า NFC ทำงานที่ความถี่ 13.56 MHz บนอินเทอร์เฟซทางอากาศ ISO/IEC 18000-3 และที่อัตราตั้งแต่ 106 กิโลบิต/วินาที ถึง 424 กิโลบิต/วินาที NFC มักประกอบด้วยตัวเริ่มต้นและเป้าหมาย ตัวเริ่มต้นจะสร้างสนาม RF ที่สามารถจ่ายพลังงานให้กับเป้าหมายแบบพาสซีฟได้ ซึ่งทำให้เป้าหมาย NFC มีรูปแบบที่เรียบง่ายมาก เช่น แท็ก สติกเกอร์ พวงกุญแจ หรือการ์ดที่ไม่ได้รับพลังงานการสื่อสารแบบเพียร์ทูเพียร์ของ NFC สามารถทำได้หากอุปกรณ์ทั้งสองมีพลังงาน
|
||||
#h(4.2em) NFC เป็นชุดเทคโนโลยีไร้สายระยะสั้น โดยทั่วไปต้องมีระยะห่าง 10 ซม.
|
||||
(#math.equation(
|
||||
alt: "3 เศษ 7 ส่วน 8",
|
||||
$3 7/8$,
|
||||
) นิ้ว) หรือน้อยกว่า NFC ทำงานที่ความถี่ 13.56 MHz บนอินเทอร์เฟซทางอากาศ ISO/IEC 18000-3
|
||||
และที่อัตราตั้งแต่ 106 กิโลบิต/วินาที ถึง 424 กิโลบิต/วินาที NFC มักประกอบด้วยตัวเริ่มต้นและเป้าหมาย
|
||||
ตัวเริ่มต้นจะสร้างสนาม RF ที่สามารถจ่ายพลังงานให้กับเป้าหมายแบบพาสซีฟได้ ซึ่งทำให้เป้าหมาย NFC
|
||||
มีรูปแบบที่เรียบง่ายมาก เช่น แท็ก สติกเกอร์ พวงกุญแจ
|
||||
หรือการ์ดที่ไม่ได้รับพลังงานการสื่อสารแบบเพียร์ทูเพียร์ของ NFC สามารถทำได้หากอุปกรณ์ทั้งสองมีพลังงาน
|
||||
|
||||
#i แท็ก NFC มีข้อมูลและโดยทั่วไปเป็นแบบอ่านอย่างเดียว แต่อาจเขียนได้ ผู้ผลิตสามารถกำหนดรหัสเองได้ หรือใช้ข้อกำหนดของ NFC Forum แท็กสามารถจัดเก็บข้อมูลส่วนบุคคลอย่างปลอดภัย เช่น ข้อมูลบัตรเดบิตและบัตรเครดิต ข้อมูลโปรแกรมสะสมคะแนน รหัส PIN และรายชื่อผู้ติดต่อในเครือข่าย
|
||||
รวมถึงข้อมูลอื่นๆ NFC Forum กำหนดแท็กห้าประเภทที่มีความเร็วและความสามารถในการสื่อสารที่แตกต่างกันในแง่ของความสามารถในการกำหนดค่าหน่วยความจำ ความปลอดภัยการเก็บข้อมูลและความทนทานต่อการเขียน
|
||||
#h(4.2em) แท็ก NFC มีข้อมูลและโดยทั่วไปเป็นแบบอ่านอย่างเดียว แต่อาจเขียนได้
|
||||
ผู้ผลิตสามารถกำหนดรหัสเองได้ หรือใช้ข้อกำหนดของ NFC Forum
|
||||
แท็กสามารถจัดเก็บข้อมูลส่วนบุคคลอย่างปลอดภัย เช่น ข้อมูลบัตรเดบิตและบัตรเครดิต
|
||||
ข้อมูลโปรแกรมสะสมคะแนน รหัส PIN และรายชื่อผู้ติดต่อในเครือข่าย รวมถึงข้อมูลอื่นๆ NFC Forum
|
||||
กำหนดแท็กห้าประเภทที่มีความเร็วและความสามารถในการสื่อสารที่แตกต่างกันในแง่ของความสามารถในการกำหนดค่าหน่วยความจำ
|
||||
ความปลอดภัยการเก็บข้อมูลและความทนทานต่อการเขียน
|
||||
|
||||
#i เช่นเดียวกับ เทคโนโลยี การ์ดแบบ Proximity NFC ใช้การเชื่อมต่อแบบเหนี่ยวนำระหว่างเสาอากาศแบบวงสองต้นที่อยู่ใกล้เคียงกัน
|
||||
ซึ่งก่อตัวเป็นหม้อแปลงแกนอากาศได้อย่างมีประสิทธิภาพเนื่องจากระยะทางที่เกี่ยวข้องนั้นน้อยมากเมื่อเทียบกับความยาวคลื่นของรังสีแม่เหล็กไฟฟ้า (คลื่นวิทยุ) ของความถี่นั้น (ประมาณ 22 เมตร) ปฏิสัมพันธ์นี้จึงถูกเรียกว่า สนามแม่เหล็กใกล้ (Near Field) สนามแม่เหล็กไฟฟ้าสลับเป็นปัจจัยการเชื่อมต่อหลัก และแทบไม่มีพลังงานแผ่ออกมาในรูปแบบของคลื่นวิทยุ (ซึ่งเป็นคลื่นแม่เหล็กไฟฟ้าที่เกี่ยวข้องกับสนามไฟฟ้าสั่นด้วย) ซึ่งช่วยลดการรบกวนระหว่างอุปกรณ์ดังกล่าวกับการสื่อสารทางวิทยุใดๆ ที่ความถี่เดียวกันหรือกับอุปกรณ์ NFC อื่นๆ ที่อยู่นอกเหนือขอบเขตที่ตั้งใจไว้ NFC ทำงานในย่านความถี่วิทยุ ISM ซึ่งใช้ทั่วโลกและไม่ได้รับอนุญาตที่ 13.56 MHz พลังงาน RF ส่วนใหญ่กระจุกตัวอยู่ในแบนด์วิดท์ ±7 kHz ที่จัดสรรให้กับย่านความถี่นั้น แต่ ความกว้างสเปกตรัมของการแผ่รังสีอาจกว้างได้ถึง 1.8 MHz เพื่อรองรับอัตราข้อมูลสูง
|
||||
#h(4.2em) เช่นเดียวกับ เทคโนโลยี การ์ดแบบ Proximity NFC
|
||||
ใช้การเชื่อมต่อแบบเหนี่ยวนำระหว่างเสาอากาศแบบวงสองต้นที่อยู่ใกล้เคียงกัน
|
||||
ซึ่งก่อตัวเป็นหม้อแปลงแกนอากาศได้อย่างมีประสิทธิภาพเนื่องจากระยะทางที่เกี่ยวข้องนั้นน้อยมากเมื่อเทียบกับความยาวคลื่นของรังสีแม่เหล็กไฟฟ้า
|
||||
(คลื่นวิทยุ) ของความถี่นั้น (ประมาณ 22 เมตร) ปฏิสัมพันธ์นี้จึงถูกเรียกว่า สนามแม่เหล็กใกล้ (Near
|
||||
Field) สนามแม่เหล็กไฟฟ้าสลับเป็นปัจจัยการเชื่อมต่อหลัก
|
||||
และแทบไม่มีพลังงานแผ่ออกมาในรูปแบบของคลื่นวิทยุ
|
||||
(ซึ่งเป็นคลื่นแม่เหล็กไฟฟ้าที่เกี่ยวข้องกับสนามไฟฟ้าสั่นด้วย)
|
||||
ซึ่งช่วยลดการรบกวนระหว่างอุปกรณ์ดังกล่าวกับการสื่อสารทางวิทยุใดๆ ที่ความถี่เดียวกันหรือกับอุปกรณ์ NFC
|
||||
อื่นๆ ที่อยู่นอกเหนือขอบเขตที่ตั้งใจไว้ NFC ทำงานในย่านความถี่วิทยุ ISM ซึ่งใช้ทั่วโลกและไม่ได้รับอนุญาตที่
|
||||
13.56 MHz พลังงาน RF ส่วนใหญ่กระจุกตัวอยู่ในแบนด์วิดท์ ±7 kHz ที่จัดสรรให้กับย่านความถี่นั้น แต่
|
||||
ความกว้างสเปกตรัมของการแผ่รังสีอาจกว้างได้ถึง 1.8 MHz เพื่อรองรับอัตราข้อมูลสูง
|
||||
|
||||
#i ระยะการทำงานด้วยเสาอากาศมาตรฐานขนาดกะทัดรัดและระดับพลังงานที่สมจริงอาจสูงถึงประมาณ 20 ซม. (#math.equation(alt: "7 เศษ 7 ส่วน 8", $7 7/8$) นิ้ว) (แต่ในทางปฏิบัติ ระยะการทำงานไม่ควรเกิน 10 ซม. หรือ #math.equation(alt: "3 เศษ 7 ส่วน 8", $3 7/8$) นิ้ว) โปรดทราบว่าเนื่องจากเสาอากาศรับสัญญาณอาจถูกดับในกระแสวนโดยพื้นผิวโลหะที่อยู่ใกล้เคียง แท็กอาจต้องแยกออกจากพื้นผิวดังกล่าวอย่างน้อยที่สุด
|
||||
#h(4.2em)
|
||||
ระยะการทำงานด้วยเสาอากาศมาตรฐานขนาดกะทัดรัดและระดับพลังงานที่สมจริงอาจสูงถึงประมาณ 20 ซม.
|
||||
(#math.equation(alt: "7 เศษ 7 ส่วน 8", $7 7/8$) นิ้ว) (แต่ในทางปฏิบัติ
|
||||
ระยะการทำงานไม่ควรเกิน 10 ซม. หรือ #math.equation(alt: "3 เศษ 7 ส่วน 8", $3 7/8$)
|
||||
นิ้ว) โปรดทราบว่าเนื่องจากเสาอากาศรับสัญญาณอาจถูกดับในกระแสวนโดยพื้นผิวโลหะที่อยู่ใกล้เคียง
|
||||
แท็กอาจต้องแยกออกจากพื้นผิวดังกล่าวอย่างน้อยที่สุด
|
||||
|
||||
มาตรฐาน ISO/IEC 18092 รองรับอัตราข้อมูล 106, 212 หรือ 424 กิโลบิต/วินาที
|
||||
|
||||
การสื่อสารเกิดขึ้นระหว่างอุปกรณ์ "ตัวเริ่มต้น" ที่ใช้งานอยู่และอุปกรณ์เป้าหมาย ซึ่งอาจเป็น:
|
||||
การสื่อสารเกิดขึ้นระหว่างอุปกรณ์ "ตัวเริ่มต้น" ที่ใช้งานอยู่และอุปกรณ์เป้าหมาย ซึ่งอาจเป็น
|
||||
|
||||
/ พาสซีฟ: อุปกรณ์ตัวเริ่มต้นจะทำหน้าที่เป็นสนามแม่เหล็กพาหะ และอุปกรณ์เป้าหมายจะสื่อสารโดยการปรับสนามแม่เหล็กตกกระทบ ในโหมดนี้ อุปกรณ์เป้าหมายอาจดึงพลังงานจากสนามแม่เหล็กที่ตัวเริ่มต้นจัดหาให้
|
||||
#[
|
||||
#set enum(indent: 4.2em)
|
||||
1. พาสซีฟ โดยอุปกรณ์ตัวเริ่มต้นจะทำหน้าที่เป็นสนามแม่เหล็กพาหะ
|
||||
และอุปกรณ์เป้าหมายจะสื่อสารโดยการปรับสนามแม่เหล็กตกกระทบ ในโหมดนี้
|
||||
อุปกรณ์เป้าหมายอาจดึงพลังงานจากสนามแม่เหล็กที่ตัวเริ่มต้นจัดหาให้
|
||||
|
||||
/ คล่องแคล่ว: ทั้งอุปกรณ์เริ่มต้นและอุปกรณ์เป้าหมายสื่อสารกันโดยการสร้างฟิลด์ของตัวเองสลับกัน อุปกรณ์จะหยุดส่งสัญญาณเพื่อรับข้อมูลจากอีกอุปกรณ์หนึ่ง โหมดนี้กำหนดให้อุปกรณ์ทั้งสองต้องมีแหล่งจ่ายไฟ
|
||||
2. คล่องแคล่ว โดยทั้งอุปกรณ์เริ่มต้นและอุปกรณ์เป้าหมายสื่อสารกันโดยการสร้างฟิลด์ของตัวเองสลับกัน
|
||||
อุปกรณ์จะหยุดส่งสัญญาณเพื่อรับข้อมูลจากอีกอุปกรณ์หนึ่ง โหมดนี้กำหนดให้อุปกรณ์ทั้งสองต้องมีแหล่งจ่ายไฟ
|
||||
]
|
||||
|
||||
#figure(
|
||||
table(
|
||||
@@ -45,12 +99,26 @@
|
||||
caption: [การเทียบความเร็วและวิธีการสื่อสารที่ใช้],
|
||||
)
|
||||
|
||||
#i NFC ใช้การเข้ารหัสสองแบบที่แตกต่างกันในการถ่ายโอนข้อมูล หากอุปกรณ์ที่ใช้งานอยู่ถ่ายโอนข้อมูลที่ความเร็ว 106 กิโลบิต/วินาที จะใช้การเข้ารหัสแบบมิลเลอร์ที่ปรับเปลี่ยนแล้วพร้อมการมอดูเลต 100 เปอร์เซ็นต์ในกรณีอื่นๆทั้งหมดจะใช้การเข้ารหัสแบบแมนเชสเตอร์โดยมีอัตราการมอดูเลต 10 เปอร์เซ็นต์
|
||||
#h(4.2em) NFC ใช้การเข้ารหัสสองแบบที่แตกต่างกันในการถ่ายโอนข้อมูล
|
||||
หากอุปกรณ์ที่ใช้งานอยู่ถ่ายโอนข้อมูลที่ความเร็ว 106 กิโลบิต/วินาที
|
||||
จะใช้การเข้ารหัสแบบมิลเลอร์ที่ปรับเปลี่ยนแล้วพร้อมการมอดูเลต 100
|
||||
เปอร์เซ็นต์ในกรณีอื่นๆทั้งหมดจะใช้การเข้ารหัสแบบแมนเชสเตอร์โดยมีอัตราการมอดูเลต 10 เปอร์เซ็นต์
|
||||
|
||||
อุปกรณ์ NFC ที่ใช้งานอยู่ทุกเครื่องสามารถทำงานในโหมดใดโหมดหนึ่งหรือหลายโหมดได้:
|
||||
#iii อุปกรณ์ NFC ที่ใช้งานอยู่ทุกเครื่องสามารถทำงานในโหมดใดโหมดหนึ่งหรือหลายโหมดได้
|
||||
|
||||
/ การจำลองการ์ด NFC: ช่วยให้อุปกรณ์ที่รองรับ NFC เช่น สมาร์ทโฟน ทำหน้าที่เหมือนสมาร์ทการ์ด ช่วยให้ผู้ใช้ทำธุรกรรมต่างๆ เช่น การชำระเงินหรือการออกตั๋วได้ ดูการจำลองการ์ดโฮสต์
|
||||
/ เครื่องอ่าน/เขียน NFC: ช่วยให้อุปกรณ์ที่เปิดใช้งาน NFC สามารถอ่านข้อมูลที่จัดเก็บไว้ในแท็ก NFC ราคาไม่แพงที่ฝังอยู่ในฉลากหรือโปสเตอร์อัจฉริยะได้
|
||||
/ NFC เพียร์ทูเพียร์: ช่วยให้อุปกรณ์ที่เปิดใช้งาน NFC สองเครื่องสามารถสื่อสารกันเพื่อแลกเปลี่ยนข้อมูลในลักษณะ เฉพาะกิจ
|
||||
#[
|
||||
#set enum(indent: 4.1em)
|
||||
1. การจำลองการ์ด NFC ช่วยให้อุปกรณ์ที่รองรับ NFC เช่น สมาร์ทโฟน ทำหน้าที่เหมือนสมาร์ทการ์ด
|
||||
ช่วยให้ผู้ใช้ทำธุรกรรมต่างๆ เช่น การชำระเงินหรือการออกตั๋วได้ ดูการจำลองการ์ดโฮสต์
|
||||
2. เครื่องอ่าน/เขียน NFC ช่วยให้อุปกรณ์ที่เปิดใช้งาน NFC สามารถอ่านข้อมูลที่จัดเก็บไว้ในแท็ก NFC
|
||||
ราคาไม่แพงที่ฝังอยู่ในฉลากหรือโปสเตอร์อัจฉริยะได้
|
||||
3. NFC เพียร์ทูเพียร์ ช่วยให้อุปกรณ์ที่เปิดใช้งาน NFC
|
||||
สองเครื่องสามารถสื่อสารกันเพื่อแลกเปลี่ยนข้อมูลในลักษณะ เฉพาะกิจ
|
||||
]
|
||||
|
||||
แท็ก NFC คือหน่วยเก็บข้อมูลแบบพาสซีฟที่อุปกรณ์ NFC สามารถอ่านและเขียนข้อมูลได้ในบางกรณี โดยทั่วไปจะมีข้อมูล (ณ ปี 2015 มีขนาดระหว่าง 96 ถึง 8,192 ไบต์) และเป็นแบบอ่านอย่างเดียวในการใช้งานปกติ แต่อาจเขียนซ้ำได้ การใช้งานรวมถึงการจัดเก็บข้อมูลส่วนบุคคลที่ปลอดภัย (เช่นข้อมูล บัตร เดบิตหรือบัตรเครดิตข้อมูลโปรแกรมสะสมคะแนน หมายเลขประจำตัว (PIN) และรายชื่อผู้ติดต่อ)\ แท็ก NFC สามารถเข้ารหัสแบบกำหนดเองโดยผู้ผลิต หรือใช้ข้อกำหนดเฉพาะของอุตสาหกรรม
|
||||
#iii แท็ก NFC คือหน่วยเก็บข้อมูลแบบพาสซีฟที่อุปกรณ์ NFC สามารถอ่านและเขียนข้อมูลได้ในบางกรณี#jb
|
||||
โดยทั่วไปจะมีข้อมูล (ณ ปี 2015 มีขนาดระหว่าง 96 ถึง 8,192 ไบต์)
|
||||
และเป็นแบบอ่านอย่างเดียวในการใช้งานปกติ แต่อาจเขียนซ้ำได้
|
||||
การใช้งานรวมถึงการจัดเก็บข้อมูลส่วนบุคคลที่ปลอดภัย (เช่นข้อมูล บัตร
|
||||
เดบิตหรือบัตรเครดิตข้อมูลโปรแกรมสะสมคะแนน หมายเลขประจำตัว (PIN) และรายชื่อผู้ติดต่อ)#jb แท็ก
|
||||
NFC สามารถเข้ารหัสแบบกำหนดเองโดยผู้ผลิต หรือใช้ข้อกำหนดเฉพาะของอุตสาหกรรม
|
||||
|
||||
@@ -1,25 +1,32 @@
|
||||
#import "../PageTemplate.typ": i
|
||||
#import "../PageTemplate.typ": *
|
||||
#set heading(numbering: "1.1", offset: 2)
|
||||
|
||||
= OpenSSL
|
||||
|
||||
#i OpenSSL คือไลบรารีซอฟต์แวร์สำหรับแอปพลิเคชันที่ให้การสื่อสารที่ปลอดภัยผ่านเครือข่ายคอมพิวเตอร์ป้องกันการดักฟังและระบุตัวบุคคลที่อยู่ปลายทาง OpenSSL ถูกใช้อย่างแพร่หลายในเซิร์ฟเวอร์อินเทอร์เน็ตรวมถึงเว็บไซต์ HTTPS ส่วนใหญ่
|
||||
OpenSSL ประกอบด้วยการนำโปรโตคอล SSL และ TLS ไปใช้งานแบบโอเพนซอร์สไลบรารีหลักที่เขียนด้วยภาษา C ทำหน้าที่เข้ารหัสข้อมูลพื้นฐานและมีฟังก์ชันยูทิลิตี้ต่างๆมากมาย มีแรปเปอร์ (Wrapper) ที่ช่วยให้สามารถใช้ไลบรารี OpenSSL ในภาษาคอมพิวเตอร์ได้หลากหลายภาษา
|
||||
#iii OpenSSL
|
||||
คือไลบรารีซอฟต์แวร์สำหรับแอปพลิเคชันที่ให้การสื่อสารที่ปลอดภัยผ่านเครือข่ายคอมพิวเตอร์ป้องกันการดักฟังและระบุตัวบุคคลที่อยู่ปลายทาง
|
||||
OpenSSL ถูกใช้อย่างแพร่หลายในเซิร์ฟเวอร์อินเทอร์เน็ตรวมถึงเว็บไซต์ HTTPS ส่วนใหญ่ OpenSSL
|
||||
ประกอบด้วยการนำโปรโตคอล SSL และ TLS ไปใช้งานแบบโอเพนซอร์สไลบรารีหลักที่เขียนด้วยภาษา C
|
||||
ทำหน้าที่เข้ารหัสข้อมูลพื้นฐานและมีฟังก์ชันยูทิลิตี้ต่างๆมากมาย มีแรปเปอร์ (Wrapper)
|
||||
ที่ช่วยให้สามารถใช้ไลบรารี OpenSSL ในภาษาคอมพิวเตอร์ได้หลากหลายภาษา
|
||||
|
||||
#i มูลนิธิซอฟต์แวร์ OpenSSL (OSF) เป็นตัวแทนของโครงการ OpenSSL ในขอบเขตทางกฎหมายส่วนใหญ่ ซึ่งรวมถึงข้อตกลงสิทธิ์การใช้งานสำหรับผู้สนับสนุนการจัดการการบริจาค และอื่นๆบริการซอฟต์แวร์ OpenSSL (OSS) ยังเป็นตัวแทนของโครงการ OpenSSL สำหรับสัญญาสนับสนุนอีกด้วย
|
||||
#iii มูลนิธิซอฟต์แวร์ OpenSSL (OSF) เป็นตัวแทนของโครงการ OpenSSL
|
||||
ในขอบเขตทางกฎหมายส่วนใหญ่ ซึ่งรวมถึงข้อตกลงสิทธิ์การใช้งานสำหรับผู้สนับสนุนการจัดการการบริจาค
|
||||
และอื่นๆบริการซอฟต์แวร์ OpenSSL (OSS) ยังเป็นตัวแทนของโครงการ OpenSSL
|
||||
สำหรับสัญญาสนับสนุนอีกด้วย
|
||||
|
||||
#i OpenSSL พร้อมใช้งานสำหรับระบบปฏิบัติการประเภท Unix ส่วนใหญ่ (รวมถึง Linux , macOS และ BSD ), Microsoft Windows และ OpenVMS
|
||||
#iii OpenSSL พร้อมใช้งานสำหรับระบบปฏิบัติการประเภท Unix ส่วนใหญ่ (รวมถึง Linux , macOS
|
||||
และ BSD ), Microsoft Windows และ OpenVMS
|
||||
|
||||
|
||||
#i OpenSSL รองรับอัลกอริทึมการเข้ารหัสที่แตกต่างกันจำนวนหนึ่ง:
|
||||
#iii OpenSSL รองรับอัลกอริทึมการเข้ารหัสที่แตกต่างกันจำนวนหนึ่ง โดยฟังก์ชันการเข้ารหัสได้แก่ AES,
|
||||
Blowfish, Camellia, ChaCha20, Poly1305, SEED, CAST-128, DES, IDEA, RC2, RC4,
|
||||
RC5, Triple DES, GOST 28147-89, SM4
|
||||
|
||||
*รหัส:*
|
||||
AES, Blowfish, Camellia, ChaCha20, Poly1305, SEED, CAST-128, DES, IDEA, RC2, RC4, RC5, Triple DES, GOST 28147-89, SM4
|
||||
#iii ฟังก์ชันแฮชการเข้ารหัสได้แก่ MD5, MD4, MD2, SHA-1, SHA-2, SHA-3, RIPEMD-160,
|
||||
MDC-2, GOST R 34.11-94, BLAKE2, วังวน, SM3
|
||||
|
||||
*ฟังก์ชันแฮชการเข้ารหัส:*
|
||||
MD5, MD4, MD2, SHA-1, SHA-2, SHA-3, RIPEMD-160, MDC-2, GOST R 34.11-94, BLAKE2, วังวน, SM3
|
||||
|
||||
*การเข้ารหัสด้วยคีย์สาธารณะ:*
|
||||
RSA, DSA, การแลกเปลี่ยนคีย์ Diffie--Hellman, เส้นโค้งวงรี, X25519, Ed25519, X448, Ed448, GOST R 34.10-2001, SM2
|
||||
#iii ฟังก์ชันการเข้ารหัสด้วยคีย์สาธารณะได้แก่ RSA, DSA, การแลกเปลี่ยนคีย์ Diffie--Hellman,
|
||||
เส้นโค้งวงรี, X25519, Ed25519, X448, Ed448, GOST R 34.10-2001, SM2
|
||||
|
||||
(การปกปิดแบบสมบูรณ์แบบได้รับการสนับสนุนโดยใช้เส้นโค้งวงรี Diffie--Hellman ตั้งแต่เวอร์ชัน 1.0)
|
||||
|
||||
@@ -5,183 +5,318 @@
|
||||
|
||||
= เซ็นเซอร์อินฟราเรดแบบพาสซีฟ (PIR sensor)
|
||||
|
||||
#i เซ็นเซอร์อินฟราเรดแบบพาสซีฟ (PIR sensor) คือ เซ็นเซอร์อิเล็กทรอนิกส์ที่วัดแสงอินฟราเรด (IR) ที่แผ่ออกมาจากวัตถุในระยะการมองเห็น เซ็นเซอร์ชนิดนี้มักใช้ในเครื่องตรวจจับความเคลื่อนไหว แบบ PIR เซ็นเซอร์ PIR มักใช้ในสัญญาณเตือนภัยและระบบไฟส่องสว่างอัตโนมัติ
|
||||
#iii เซ็นเซอร์อินฟราเรดแบบพาสซีฟ (PIR sensor) คือ เซ็นเซอร์อิเล็กทรอนิกส์ที่วัดแสงอินฟราเรด
|
||||
(IR) ที่แผ่ออกมาจากวัตถุในระยะการมองเห็น เซ็นเซอร์ชนิดนี้มักใช้ในเครื่องตรวจจับความเคลื่อนไหว แบบ
|
||||
PIR เซ็นเซอร์ PIR มักใช้ในสัญญาณเตือนภัยและระบบไฟส่องสว่างอัตโนมัติ
|
||||
|
||||
#v(1em)
|
||||
|
||||
#afigure(
|
||||
image("PIR/Front-Fresnel_type.jpg", height: image-height),
|
||||
attr: [Jack LaRosa, Public Domain, https://commons.wikimedia.org/w/index.php?curid=4479143],
|
||||
attr: [Jack LaRosa, Public Domain,
|
||||
https://commons.wikimedia.org/w/index.php?curid=4479143],
|
||||
alt: "เซนเซอร์ตรวจจับการเคลื่อนไหวทรงสี่เหลี่ยมผืนผ้าแนวตั้ง",
|
||||
caption: [เครื่องตรวจจับการเคลื่อนไหวแบบ PIR ทั่วไปสำหรับที่พักอาศัย/เชิงพาณิชย์],
|
||||
)
|
||||
|
||||
#i เซ็นเซอร์ PIR ตรวจจับการเคลื่อนไหวทั่วไป แต่ไม่ได้ให้ข้อมูลว่าใครหรือสิ่งใดเคลื่อนไหว ดังนั้น จึงจำเป็นต้องใช้ เซ็นเซอร์ IR แบบสร้างภาพ เซ็นเซอร์ PIR มักเรียกสั้นๆ ว่า "PIR" หรือบางครั้งเรียกว่า "PID" ซึ่งย่อมาจาก "เครื่องตรวจจับอินฟราเรดแบบพาสซีฟ" เซ็นเซอร์ PIR ตรวจจับการเคลื่อนไหวทั่วไป แต่ไม่ได้ให้ข้อมูลว่าใครหรือสิ่งใดเคลื่อนไหว ดังนั้น จึงจำเป็นต้องใช้ เซ็นเซอร์ IR แบบสร้างภาพ เซ็นเซอร์ PIR มักเรียกสั้นๆ ว่า "PIR" หรือบางครั้งเรียกว่า "PID" ซึ่งย่อมาจาก "เครื่องตรวจจับอินฟราเรดแบบพาสซีฟ" คำว่าพาสซีฟหมายถึงข้อเท็จจริงที่ว่าอุปกรณ์ PIR ไม่ได้แผ่พลังงานเพื่อจุดประสงค์ในการตรวจจับ แต่ทำงานโดยการตรวจจับรังสีอินฟราเรด (ความร้อนจากการแผ่รังสี) ที่แผ่ออกมาจากหรือสะท้อนจากวัตถุ เท่านั้นซีฟ" คำว่าพาสซีฟหมายถึงข้อเท็จจริงที่ว่าอุปกรณ์ PIR ไม่ได้แผ่พลังงานเพื่อจุดประสงค์ในการตรวจจับ แต่ทำงานโดยการตรวจจับรังสีอินฟราเรด (ความร้อนจากการแผ่รังสี) ที่แผ่ออกมาจากหรือสะท้อนจากวัตถุ เท่านั้น
|
||||
#v(0.5em)
|
||||
|
||||
#iii เซ็นเซอร์ PIR ตรวจจับการเคลื่อนไหวทั่วไป แต่ไม่ได้ให้ข้อมูลว่าใครหรือสิ่งใดเคลื่อนไหว#jb ดังนั้น
|
||||
จึงจำเป็นต้องใช้ เซ็นเซอร์ IR แบบสร้างภาพ เซ็นเซอร์ PIR มักเรียกสั้นๆ ว่า "PIR"
|
||||
หรือบางครั้งเรียกว่า "PID" ซึ่งย่อมาจาก "เครื่องตรวจจับอินฟราเรดแบบพาสซีฟ" เซ็นเซอร์ PIR
|
||||
ตรวจจับการเคลื่อนไหวทั่วไป แต่ไม่ได้ให้ข้อมูลว่าใครหรือสิ่งใดเคลื่อนไหว ดังนั้น จึงจำเป็นต้องใช้ เซ็นเซอร์
|
||||
IR แบบสร้างภาพ เซ็นเซอร์ PIR มักเรียกสั้นๆ ว่า "PIR" หรือบางครั้งเรียกว่า "PID" ซึ่งย่อมาจาก
|
||||
"เครื่องตรวจจับอินฟราเรดแบบพาสซีฟ" คำว่าพาสซีฟหมายถึงข้อเท็จจริงที่ว่าอุปกรณ์ PIR
|
||||
ไม่ได้แผ่พลังงานเพื่อจุดประสงค์ในการตรวจจับ แต่ทำงานโดยการตรวจจับรังสีอินฟราเรด
|
||||
(ความร้อนจากการแผ่รังสี) ที่แผ่ออกมาจากหรือสะท้อนจากวัตถุ เท่านั้นซีฟ"
|
||||
คำว่าพาสซีฟหมายถึงข้อเท็จจริงที่ว่าอุปกรณ์ PIR ไม่ได้แผ่พลังงานเพื่อจุดประสงค์ในการตรวจจับ
|
||||
แต่ทำงานโดยการตรวจจับรังสีอินฟราเรด (ความร้อนจากการแผ่รังสี) ที่แผ่ออกมาจากหรือสะท้อนจากวัตถุ
|
||||
เท่านั้น
|
||||
|
||||
== หลักการทำงาน
|
||||
|
||||
#i วัตถุทุกชนิดที่มีอุณหภูมิสูงกว่าศูนย์องศาสัมบูรณ์จะปล่อยพลังงานความร้อนออกมาในรูปของรังสีแม่เหล็กไฟฟ้า โดยปกติแล้วรังสีนี้มองไม่เห็นด้วยตาเปล่าเนื่องจากแผ่รังสีในช่วงความยาวคลื่นอินฟราเรด แต่อุปกรณ์อิเล็กทรอนิกส์ที่ออกแบบมาเพื่อจุดประสงค์นี้ สามารถตรวจจับได้
|
||||
#iiii
|
||||
วัตถุทุกชนิดที่มีอุณหภูมิสูงกว่าศูนย์องศาสัมบูรณ์จะปล่อยพลังงานความร้อนออกมาในรูปของรังสีแม่เหล็กไฟฟ้า
|
||||
โดยปกติแล้วรังสีนี้มองไม่เห็นด้วยตาเปล่าเนื่องจากแผ่รังสีในช่วงความยาวคลื่นอินฟราเรด
|
||||
แต่อุปกรณ์อิเล็กทรอนิกส์ที่ออกแบบมาเพื่อจุดประสงค์นี้ สามารถตรวจจับได้
|
||||
|
||||
== เครื่องตรวจจับการเคลื่อนไหวแบบ PIR
|
||||
|
||||
#afigure(
|
||||
image("PIR/Motion_detector.jpg", height: image-height),
|
||||
image("PIR/Motion_detector.jpg", height: 2in),
|
||||
alt: "เครื่องตรวจจับความเคลื่อนไหว ติดตั้งบนเพดาน",
|
||||
attr: [CHG, Public Domain, https://commons.wikimedia.org/w/index.php?curid=6087132],
|
||||
caption: [เครื่องตรวจจับความเคลื่อนไหว PIR
|
||||
ใช้สำหรับควบคุมไฟภายนอกอาคารแบบอัตโนมัติ],
|
||||
attr: [CHG, Public Domain,
|
||||
https://commons.wikimedia.org/w/index.php?curid=6087132],
|
||||
caption: [เครื่องตรวจจับความเคลื่อนไหว PIR ใช้สำหรับควบคุมไฟภายนอกอาคารแบบอัตโนมัติ],
|
||||
)
|
||||
|
||||
#afigure(
|
||||
image("PIR/Camera_trap,_fotopułapka,_kamera_leśna,_kamera_obserwacyjna.jpg"),
|
||||
attr: [Dariusz Kowalczyk, CC BY-SA 4.0, https://commons.wikimedia.org/w/index.php?curid=96211951],
|
||||
attr: [Dariusz Kowalczyk, CC BY-SA 4.0,
|
||||
https://commons.wikimedia.org/w/index.php?curid=96211951],
|
||||
alt: "กล้องดักถ่ายที่ถูกพันรอบต้นไม้",
|
||||
caption: [กล้องดักถ่ายพร้อมระบบตรวจจับความเคลื่อนไหวแบบ PIR],
|
||||
)
|
||||
|
||||
#afigure(
|
||||
image("PIR/Light_switch_with_passive_infrared_sensor.jpg", height: image-height),
|
||||
image(
|
||||
"PIR/Light_switch_with_passive_infrared_sensor.jpg",
|
||||
height: image-height,
|
||||
),
|
||||
alt: "สวิตช์ไฟทรงสี่เหลี่ยมผืนผ้าแนวตั้งที่ติดตั้งเซนเซอร์ตรวจจับคน",
|
||||
attr: [Z22, CC BY-SA 4.0, https://commons.wikimedia.org/w/index.php?curid=35183184],
|
||||
attr: [Z22, CC BY-SA 4.0,
|
||||
https://commons.wikimedia.org/w/index.php?curid=35183184],
|
||||
caption: [สวิตช์ไฟภายในอาคารที่ติดตั้งเซนเซอรตรวจจับการครอบครองแบบ PIR],
|
||||
)
|
||||
|
||||
#i เครื่องตรวจจับความเคลื่อนไหวแบบ PIR ใช้เพื่อตรวจจับการเคลื่อนไหวของคน สัตว์ หรือวัตถุอื่นๆ มักใช้กับสัญญาณกันขโมยและระบบไฟส่องสว่างแบบอัตโนมัติ
|
||||
#iiii เครื่องตรวจจับความเคลื่อนไหวแบบ PIR ใช้เพื่อตรวจจับการเคลื่อนไหวของคน สัตว์ หรือวัตถุอื่นๆ
|
||||
มักใช้กับสัญญาณกันขโมยและระบบไฟส่องสว่างแบบอัตโนมัติ
|
||||
|
||||
== การดำเนินการ
|
||||
|
||||
#i เซ็นเซอร์ PIR สามารถตรวจจับการเปลี่ยนแปลงของปริมาณรังสีอินฟราเรดที่กระทบกับวัตถุ ซึ่งจะแตกต่างกันไปขึ้นอยู่กับอุณหภูมิและลักษณะพื้นผิวของวัตถุที่อยู่ด้านหน้าเซ็นเซอร์เมื่อวัตถุ เช่น บุคคล ผ่านด้านหน้าพื้นหลัง เช่น กำแพง อุณหภูมิ ณ จุดนั้นในมุมมองของเซ็นเซอร์จะเพิ่มขึ้นจากอุณหภูมิห้องเป็นอุณหภูมิร่างกายแล้วกลับมาอีกครั้ง เซ็นเซอร์จะแปลงการเปลี่ยนแปลงที่เกิดขึ้นของรังสีอินฟราเรดที่เข้ามาเป็นการเปลี่ยนแปลงของแรงดันไฟฟ้าขาออก และสิ่งนี้จะกระตุ้นการตรวจจับ วัตถุที่มีอุณหภูมิใกล้เคียงกันแต่มีลักษณะพื้นผิวต่างกันอาจมีรูปแบบการปล่อยรังสีอินฟราเรดที่แตกต่างกัน ดังนั้นการเคลื่อนย้ายวัตถุเทียบกับพื้นหลังอาจกระตุ้นเครื่องตรวจจับได้เช่นกัน
|
||||
#iiii เซ็นเซอร์ PIR สามารถตรวจจับการเปลี่ยนแปลงของปริมาณรังสีอินฟราเรดที่กระทบกับวัตถุ
|
||||
ซึ่งจะแตกต่างกันไปขึ้นอยู่กับอุณหภูมิและลักษณะพื้นผิวของวัตถุที่อยู่ด้านหน้าเซ็นเซอร์เมื่อวัตถุ เช่น บุคคล
|
||||
ผ่านด้านหน้าพื้นหลัง เช่น กำแพง อุณหภูมิ ณ
|
||||
จุดนั้นในมุมมองของเซ็นเซอร์จะเพิ่มขึ้นจากอุณหภูมิห้องเป็นอุณหภูมิร่างกายแล้วกลับมาอีกครั้ง
|
||||
เซ็นเซอร์จะแปลงการเปลี่ยนแปลงที่เกิดขึ้นของรังสีอินฟราเรดที่เข้ามาเป็นการเปลี่ยนแปลงของแรงดันไฟฟ้าขาออก
|
||||
และสิ่งนี้จะกระตุ้นการตรวจจับ
|
||||
วัตถุที่มีอุณหภูมิใกล้เคียงกันแต่มีลักษณะพื้นผิวต่างกันอาจมีรูปแบบการปล่อยรังสีอินฟราเรดที่แตกต่างกัน
|
||||
ดังนั้นการเคลื่อนย้ายวัตถุเทียบกับพื้นหลังอาจกระตุ้นเครื่องตรวจจับได้เช่นกัน
|
||||
|
||||
#i PIR มีหลายรูปแบบการใช้งานที่หลากหลาย รุ่นที่นิยมใช้กันมากที่สุดมีเลนส์เฟรสเนลหรือส่วนกระจกจำนวนมาก ระยะการทำงานประมาณ 10 เมตร (30 ฟุต) และมุมมองภาพน้อยกว่า 180° มีรุ่นที่มีมุมมองภาพกว้างกว่า รวมถึง 360° ซึ่งโดยทั่วไปออกแบบมาเพื่อติดตั้งบนเพดาน PIR ขนาดใหญ่บางรุ่นผลิตด้วยกระจกส่วนเดียวและสามารถตรวจจับการเปลี่ยนแปลงของพลังงานอินฟราเรดได้ในระยะ 30 เมตร (100 ฟุต) จาก PIR นอกจากนี้ยังมี PIR ที่ออกแบบด้วยกระจกแบบปรับทิศทางได้ ซึ่งสามารถครอบคลุมพื้นที่ได้กว้าง (110°) หรือครอบคลุมพื้นที่แคบมากแบบ "ม่าน" หรือสามารถเลือกส่วนกระจกแยกแต่ละส่วนเพื่อ "ปรับแต่ง" พื้นที่ครอบคลุมได้
|
||||
#iiii PIR มีหลายรูปแบบการใช้งานที่หลากหลาย
|
||||
รุ่นที่นิยมใช้กันมากที่สุดมีเลนส์เฟรสเนลหรือส่วนกระจกจำนวนมาก ระยะการทำงานประมาณ 10 เมตร (30
|
||||
ฟุต) และมุมมองภาพน้อยกว่า 180° มีรุ่นที่มีมุมมองภาพกว้างกว่า รวมถึง 360°
|
||||
ซึ่งโดยทั่วไปออกแบบมาเพื่อติดตั้งบนเพดาน PIR
|
||||
ขนาดใหญ่บางรุ่นผลิตด้วยกระจกส่วนเดียวและสามารถตรวจจับการเปลี่ยนแปลงของพลังงานอินฟราเรดได้ในระยะ
|
||||
30 เมตร (100 ฟุต) จาก PIR นอกจากนี้ยังมี PIR ที่ออกแบบด้วยกระจกแบบปรับทิศทางได้
|
||||
ซึ่งสามารถครอบคลุมพื้นที่ได้กว้าง (110°) หรือครอบคลุมพื้นที่แคบมากแบบ "ม่าน"
|
||||
หรือสามารถเลือกส่วนกระจกแยกแต่ละส่วนเพื่อ "ปรับแต่ง" พื้นที่ครอบคลุมได้
|
||||
|
||||
== การตรวจจับความแตกต่าง
|
||||
|
||||
#i เซ็นเซอร์หลายตัวอาจเชื่อมต่อเป็นอินพุตตรงข้ามกับเครื่องขยายสัญญาณดิฟเฟอเรนเชียล ในรูปแบบนี้ การวัดค่า PIR จะหักล้างกันเอง ทำให้อุณหภูมิเฉลี่ยของระยะการมองเห็นถูกตัดออกจากสัญญาณไฟฟ้า การเพิ่มขึ้นของพลังงานอินฟราเรดทั่วทั้งเซ็นเซอร์จะหักล้างตัวเองและจะไม่กระตุ้นอุปกรณ์ วิธีนี้ช่วยให้อุปกรณ์ต้านทานการเปลี่ยนแปลงที่ผิดพลาดในกรณีที่ได้รับแสงแฟลชสั้นๆ หรือแสงที่ส่องสว่างทั่วทั้งสนาม (การได้รับพลังงานสูงอย่างต่อเนื่องอาจทำให้วัสดุเซ็นเซอร์อิ่มตัวและทำให้เซ็นเซอร์ไม่สามารถบันทึกข้อมูลเพิ่มเติมได้) ในขณะเดียวกัน การจัดเรียงแบบดิฟเฟอเรนเชียลนี้ยังช่วยลดสัญญาณรบกวนโหมดทั่วไปทำให้อุปกรณ์ต้านทานการกระตุ้นเนื่องจากสนามไฟฟ้าใกล้เคียง อย่างไรก็ตาม เซ็นเซอร์แบบดิฟเฟอเรนเชียลคู่ไม่สามารถวัดอุณหภูมิได้ในรูปแบบนี้ ดังนั้นจึงมีประโยชน์เฉพาะสำหรับการตรวจจับการเคลื่อนไหวเท่านั้น
|
||||
#iiii เซ็นเซอร์หลายตัวอาจเชื่อมต่อเป็นอินพุตตรงข้ามกับเครื่องขยายสัญญาณดิฟเฟอเรนเชียล ในรูปแบบนี้
|
||||
การวัดค่า PIR จะหักล้างกันเอง ทำให้อุณหภูมิเฉลี่ยของระยะการมองเห็นถูกตัดออกจากสัญญาณไฟฟ้า
|
||||
การเพิ่มขึ้นของพลังงานอินฟราเรดทั่วทั้งเซ็นเซอร์จะหักล้างตัวเองและจะไม่กระตุ้นอุปกรณ์
|
||||
วิธีนี้ช่วยให้อุปกรณ์ต้านทานการเปลี่ยนแปลงที่ผิดพลาดในกรณีที่ได้รับแสงแฟลชสั้นๆ
|
||||
หรือแสงที่ส่องสว่างทั่วทั้งสนาม
|
||||
(การได้รับพลังงานสูงอย่างต่อเนื่องอาจทำให้วัสดุเซ็นเซอร์อิ่มตัวและทำให้เซ็นเซอร์ไม่สามารถบันทึกข้อมูลเพิ่มเติมได้)
|
||||
ในขณะเดียวกัน
|
||||
การจัดเรียงแบบดิฟเฟอเรนเชียลนี้ยังช่วยลดสัญญาณรบกวนโหมดทั่วไปทำให้อุปกรณ์ต้านทานการกระตุ้นเนื่องจากสนามไฟฟ้าใกล้เคียง
|
||||
อย่างไรก็ตาม เซ็นเซอร์แบบดิฟเฟอเรนเชียลคู่ไม่สามารถวัดอุณหภูมิได้ในรูปแบบนี้
|
||||
ดังนั้นจึงมีประโยชน์เฉพาะสำหรับการตรวจจับการเคลื่อนไหวเท่านั้น
|
||||
|
||||
== การปฏิบัติจริง
|
||||
|
||||
#i เมื่อเซ็นเซอร์ PIR ถูกกำหนดค่าในโหมดดิฟเฟอเรนเชียล เซ็นเซอร์จะสามารถใช้งานได้เฉพาะในฐานะอุปกรณ์ตรวจจับการเคลื่อนไหว ในโหมดนี้ เมื่อตรวจจับการเคลื่อนไหวภายใน "แนวสายตา" ของเซ็นเซอร์ พัลส์เสริมคู่หนึ่งจะถูกประมวลผลที่ขาเอาต์พุตของเซ็นเซอร์ เพื่อนำสัญญาณเอาต์พุตนี้ไปใช้งานจริงในการกระตุ้นโหลด เช่น รีเลย์หรือเครื่องบันทึกข้อมูลหรือสัญญาณเตือนสัญญาณดิฟเฟอเรน-เชียลจะถูกแก้ไขโดยใช้วงจรเรียงกระแสแบบบริดจ์และป้อนเข้าสู่วงจรขับรีเลย์แบบทรานซิสเตอร์ หน้าสัมผัสของรีเลย์นี้จะปิดและเปิดเพื่อตอบสนองต่อสัญญาณจาก PIR โดยกระตุ้นโหลดที่เชื่อมต่ออยู่ผ่านหน้าสัมผัสของมัน รับรู้ถึงการตรวจจับบุคคลภายในพื้นที่จำกัดที่กำหนดไว้ล่วงหน้า
|
||||
#iiii เมื่อเซ็นเซอร์ PIR ถูกกำหนดค่าในโหมดดิฟเฟอเรนเชียล
|
||||
เซ็นเซอร์จะสามารถใช้งานได้เฉพาะในฐานะอุปกรณ์ตรวจจับการเคลื่อนไหว ในโหมดนี้
|
||||
เมื่อตรวจจับการเคลื่อนไหวภายใน "แนวสายตา" ของเซ็นเซอร์
|
||||
พัลส์เสริมคู่หนึ่งจะถูกประมวลผลที่ขาเอาต์พุตของเซ็นเซอร์
|
||||
เพื่อนำสัญญาณเอาต์พุตนี้ไปใช้งานจริงในการกระตุ้นโหลด เช่น
|
||||
รีเลย์หรือเครื่องบันทึกข้อมูลหรือสัญญาณเตือนสัญญาณดิฟเฟอเรน-เชียลจะถูกแก้ไขโดยใช้วงจรเรียงกระแสแบบบริดจ์และป้อนเข้าสู่วงจรขับรีเลย์แบบทรานซิสเตอร์
|
||||
หน้าสัมผัสของรีเลย์นี้จะปิดและเปิดเพื่อตอบสนองต่อสัญญาณจาก PIR
|
||||
โดยกระตุ้นโหลดที่เชื่อมต่ออยู่ผ่านหน้าสัมผัสของมัน
|
||||
รับรู้ถึงการตรวจจับบุคคลภายในพื้นที่จำกัดที่กำหนดไว้ล่วงหน้า
|
||||
|
||||
== การออกแบบผลิตภัณฑ์
|
||||
|
||||
#afigure(
|
||||
image("PIR/PIR_Motion_Sensor-Sensinova_(SN-PR11).png", height: image-height),
|
||||
attr: [Versatile Techno - http://www.sensinova.in/pir-motion-sensor/SNPR11.php, CC BY-SA 4.0, https://commons.wikimedia.org/w/index.php?curid=48377787],
|
||||
image("PIR/PIR_Motion_Sensor-Sensinova_(SN-PR11).png", height: 1.75in),
|
||||
attr: [Versatile Techno -
|
||||
http://www.sensinova.in/pir-motion-sensor/SNPR11.php, CC BY-SA 4.0,
|
||||
https://commons.wikimedia.org/w/index.php?curid=48377787],
|
||||
alt: "ผลิตภัณฑ์เซนเซอร์สีขาว มีเครื่องหมายแบรนด์ Sensinova",
|
||||
caption: [การออกแบบเซ็นเซอร์ตรวจจับการเคลื่อนไหว PIR],
|
||||
)
|
||||
|
||||
#i โดยทั่วไปเซ็นเซอร์ PIR จะติดตั้งอยู่บนแผงวงจรพิมพ์ซึ่งมีอุปกรณ์อิเล็กทรอนิกส์ที่จำเป็นสำหรับการตีความสัญญาณจากตัวเซ็นเซอร์เอง โดยทั่วไปแล้วชุดประกอบทั้งหมดจะบรรจุอยู่ภายในตัวเรือน ซึ่งติดตั้งในตำแหน่งที่เซ็นเซอร์สามารถครอบคลุมพื้นที่ที่ต้องการตรวจสอบได้ ตัวเรือนมักจะมี "หน้าต่าง" พลาสติกที่พลังงานอินฟราเรดสามารถผ่านเข้ามาได้ แม้ว่ามักจะโปร่งแสงต่อแสงที่มองเห็น แต่พลังงานอินฟราเรดสามารถผ่านเข้ามายังเซ็นเซอร์ได้ผ่านหน้าต่าง เนื่องจากพลาสติกที่ใช้นั้นโปร่งใสต่อรังสีอินฟราเรด หน้าต่างพลาสติกช่วยลดโอกาสที่วัตถุแปลกปลอม (ฝุ่น แมลง ฝน ฯลฯ) จะบดบังมุมมองของเซ็นเซอร์ ทำให้กลไกเสียหาย และอาจทำให้เกิดสัญญาณเตือนที่ผิดพลาด หน้าต่างนี้สามารถใช้เป็นตัวกรองเพื่อจำกัดความยาวคลื่นให้อยู่ที่ 8-14 ไมโครเมตร ซึ่งใกล้เคียงกับรังสีอินฟราเรดที่มนุษย์ปล่อยออกมามากที่สุด นอกจากนี้ยังสามารถใช้เป็นกลไกโฟกัสได้อีกด้วย (ดูด้านล่าง)
|
||||
#v(1em)
|
||||
|
||||
#iiii โดยทั่วไปเซ็นเซอร์ PIR
|
||||
จะติดตั้งอยู่บนแผงวงจรพิมพ์ซึ่งมีอุปกรณ์อิเล็กทรอนิกส์ที่จำเป็นสำหรับการตีความสัญญาณจากตัวเซ็นเซอร์เอง
|
||||
โดยทั่วไปแล้วชุดประกอบทั้งหมดจะบรรจุอยู่ภายในตัวเรือน
|
||||
ซึ่งติดตั้งในตำแหน่งที่เซ็นเซอร์สามารถครอบคลุมพื้นที่ที่ต้องการตรวจสอบได้ ตัวเรือนมักจะมี "หน้าต่าง"
|
||||
พลาสติกที่พลังงานอินฟราเรดสามารถผ่านเข้ามาได้ แม้ว่ามักจะโปร่งแสงต่อแสงที่มองเห็น
|
||||
แต่พลังงานอินฟราเรดสามารถผ่านเข้ามายังเซ็นเซอร์ได้ผ่านหน้าต่าง
|
||||
เนื่องจากพลาสติกที่ใช้นั้นโปร่งใสต่อรังสีอินฟราเรด หน้าต่างพลาสติกช่วยลดโอกาสที่วัตถุแปลกปลอม (ฝุ่น
|
||||
แมลง ฝน ฯลฯ)#jb จะบดบังมุมมองของเซ็นเซอร์ ทำให้กลไกเสียหาย
|
||||
และอาจทำให้เกิดสัญญาณเตือนที่ผิดพลาด หน้าต่างนี้สามารถใช้เป็นตัวกรองเพื่อจำกัดความยาวคลื่นให้อยู่ที่
|
||||
8-14 ไมโครเมตร ซึ่งใกล้เคียงกับรังสีอินฟราเรดที่มนุษย์ปล่อยออกมามากที่สุด
|
||||
นอกจากนี้ยังสามารถใช้เป็นกลไกโฟกัสได้อีกด้วย (ดูด้านล่าง)
|
||||
|
||||
== การโฟกัส
|
||||
|
||||
#i สามารถใช้กลไกที่แตกต่างกันเพื่อโฟกัสพลังงานอินฟราเรดระยะไกลลงบนพื้นผิวเซ็นเซอร์ได้
|
||||
#iiii สามารถใช้กลไกที่แตกต่างกันเพื่อโฟกัสพลังงานอินฟราเรดระยะไกลลงบนพื้นผิวเซ็นเซอร์ได้
|
||||
|
||||
== เลนส์
|
||||
|
||||
#i ม่านพลาสติกอาจหล่อขึ้นรูปหลายเหลี่ยมเพื่อรวมพลังงานอินฟราเรดไปยังเซ็นเซอร์ แต่ละเหลี่ยมคือเลนส์เฟรสเนล
|
||||
#iiii ม่านพลาสติกอาจหล่อขึ้นรูปหลายเหลี่ยมเพื่อรวมพลังงานอินฟราเรดไปยังเซ็นเซอร์
|
||||
แต่ละเหลี่ยมคือเลนส์เฟรสเนล
|
||||
|
||||
=== เลนส์มัลติเฟรสเนลของ PIR
|
||||
#h(12em) 1) เลนส์มัลติเฟรสเนลของ PIR
|
||||
|
||||
#afigure(
|
||||
image("PIR/FacetLensOfMotionDetector_animation2.gif", height: 2in),
|
||||
image("PIR/FacetLensOfMotionDetector_animation2.gif", height: 1.75in),
|
||||
attr: [CC BY-SA 3.0, https://en.wikipedia.org/w/index.php?curid=14193664],
|
||||
alt: "เครื่องตรวจจับความเคลื่อนไหวทรงกระบอก",
|
||||
caption: [ตัวเรือนเครื่องตรวจจับความเคลื่อนไหว PIR พร้อมช่องหน้าต่างทรงกระบอกเหลี่ยมโดยแต่ละเหลี่ยมเป็นเลนส์เฟรสเนล โฟกัสแสงไปที่ชิ้นส่วนเซ็นเซอร์ไพโรอิเล็กทริกที่อยู่ด้านล่าง],
|
||||
caption: [ตัวเรือนเครื่องตรวจจับความเคลื่อนไหว PIR
|
||||
พร้อมช่องหน้าต่างทรงกระบอกเหลี่ยมโดยแต่ละเหลี่ยมเป็นเลนส์เฟรสเนล
|
||||
โฟกัสแสงไปที่ชิ้นส่วนเซ็นเซอร์ไพโรอิเล็กทริกที่อยู่ด้านล่าง],
|
||||
)
|
||||
|
||||
#v(3em)
|
||||
|
||||
#afigure(
|
||||
image("PIR/Fresnel_only.jpg", height: 2in),
|
||||
attr: [Jack LaRosa, Public Domain, https://commons.wikimedia.org/w/index.php?curid=4463018],
|
||||
attr: [Jack LaRosa, Public Domain,
|
||||
https://commons.wikimedia.org/w/index.php?curid=4463018],
|
||||
alt: "ฝาครอบของเซนเซอร์ตรวจจับความเคลื่อนไหว",
|
||||
caption: [ฝาครอบด้านหน้า PIR เท่านั้น (ถอดอุปกรณ์อิเล็กทรอนิกส์ออก) โดยมีแหล่งกำเนิดแสงจุดอยู่ด้านหลัง เพื่อแสดงเลนส์แต่ละตัว],
|
||||
caption: [ฝาครอบด้านหน้า PIR เท่านั้น (ถอดอุปกรณ์อิเล็กทรอนิกส์ออก)
|
||||
โดยมีแหล่งกำเนิดแสงจุดอยู่ด้านหลัง เพื่อแสดงเลนส์แต่ละตัว],
|
||||
)
|
||||
|
||||
#v(3em)
|
||||
|
||||
#afigure(
|
||||
image("PIR/Circuit_board_revealed.jpg", height: 2in),
|
||||
attr: [Jack LaRosa, Public Domain, https://commons.wikimedia.org/w/index.php?curid=4478366],
|
||||
attr: [Jack LaRosa, Public Domain,
|
||||
https://commons.wikimedia.org/w/index.php?curid=4478366],
|
||||
alt: "แผงวงจร PIR ลูกศรสีเขียวชี้ไปยังเซนเซอร์ภายในบอร์ด",
|
||||
caption: [PIR ที่ถอดฝาครอบด้านหน้าออก แสดงตำแหน่งของ
|
||||
เซ็นเซอร์ไพโรอิเล็กทริก (ลูกศรสีเขียว)],
|
||||
caption: [PIR ที่ถอดฝาครอบด้านหน้าออก แสดงตำแหน่งของ เซ็นเซอร์ไพโรอิเล็กทริก
|
||||
(ลูกศรสีเขียว)],
|
||||
)
|
||||
|
||||
== กระจก PIR
|
||||
|
||||
#i บางรุ่นผลิตขึ้นโดยใช้กระจกพาราโบลา แบบแบ่งส่วนภายใน เพื่อรวมพลังงานอินฟราเรด ในกรณีที่ใช้กระจก ฝาครอบกระจกพลาสติกโดยทั่วไปจะไม่มีเลนส์เฟรสเนลหล่อขึ้นรูป
|
||||
#iiii บางรุ่นผลิตขึ้นโดยใช้กระจกพาราโบลา แบบแบ่งส่วนภายใน เพื่อรวมพลังงานอินฟราเรด
|
||||
ในกรณีที่ใช้กระจก ฝาครอบกระจกพลาสติกโดยทั่วไปจะไม่มีเลนส์เฟรสเนลหล่อขึ้นรูป
|
||||
|
||||
=== PIR ชนิดกระจกแบ่งส่วน
|
||||
#iiii 1) PIR ชนิดกระจกแบ่งส่วน
|
||||
|
||||
#afigure(
|
||||
image("PIR/Front-(mirror_type).jpg", height: 2in),
|
||||
attr: [Jack LaRosa, Public Domain, https://commons.wikimedia.org/w/index.php?curid=4501665],
|
||||
attr: [Jack LaRosa, Public Domain,
|
||||
https://commons.wikimedia.org/w/index.php?curid=4501665],
|
||||
alt: "เซนเซอร์ทรงคล้ายทรงกลม",
|
||||
caption: [PID ทั่วไปสำหรับที่พักอาศัย/เชิงพาณิชย์ที่
|
||||
ใช้กระจกแบ่งส่วนภายในเพื่อการโฟกัส],
|
||||
caption: [PID ทั่วไปสำหรับที่พักอาศัย/เชิงพาณิชย์ที่ ใช้กระจกแบ่งส่วนภายในเพื่อการโฟกัส],
|
||||
)
|
||||
|
||||
#v(1em)
|
||||
|
||||
#afigure(
|
||||
image("PIR/Mirror_type_opened.jpg", height: 2in),
|
||||
attr: [Deuxdad, Public Domain, https://commons.wikimedia.org/w/index.php?curid=4501724],
|
||||
attr: [Deuxdad, Public Domain,
|
||||
https://commons.wikimedia.org/w/index.php?curid=4501724],
|
||||
alt: "เซนเซอร์ก่อนหน้าเมื่อถูกถอดฝาครอบออก",
|
||||
caption: [ถอดฝาครอบออกแล้ว กระจกแบ่งส่วน
|
||||
ด้านล่างมีแผงวงจรพิมพ์ (PC) อยู่ด้านบน],
|
||||
caption: [ถอดฝาครอบออกแล้ว กระจกแบ่งส่วน ด้านล่างมีแผงวงจรพิมพ์ (PC) อยู่ด้านบน],
|
||||
)
|
||||
|
||||
#v(1em)
|
||||
|
||||
#afigure(
|
||||
image("PIR/Mirror_in_place.jpg", height: 2in),
|
||||
attr: [Jack LaRosa, Public Domain, https://commons.wikimedia.org/w/index.php?curid=4502198],
|
||||
attr: [Jack LaRosa, Public Domain,
|
||||
https://commons.wikimedia.org/w/index.php?curid=4502198],
|
||||
alt: "เซนเซอร์ก่อนหน้าเมื่อถอดแผงวงจรให้เห็นกระจกแบ่งส่วนด้านใน",
|
||||
caption: [แผงวงจรพิมพ์ถูกถอดออกเพื่อแสดงกระจกแบบแบ่งส่วน],
|
||||
)
|
||||
|
||||
#afigure(
|
||||
image("PIR/Segmented-parabolic_mirror.jpg", height: 2in),
|
||||
attr: [Deuxdad, Public Domain, https://commons.wikimedia.org/w/index.php?curid=4502224],
|
||||
attr: [Deuxdad, Public Domain,
|
||||
https://commons.wikimedia.org/w/index.php?curid=4502224],
|
||||
alt: "กระจกแบ่งส่วนที่ถูกถอดออก",
|
||||
caption: [กระจกพาราโบลาแบบแบ่งส่วนถอดออกจากตัวเครื่อง],
|
||||
)
|
||||
|
||||
#v(1em)
|
||||
|
||||
#afigure(
|
||||
image("PIR/Rear_of_circuit_board2.jpg", height: 2in),
|
||||
attr: [Jack LaRosa, Public Domain, https://commons.wikimedia.org/w/index.php?curid=4508036],
|
||||
attr: [Jack LaRosa, Public Domain,
|
||||
https://commons.wikimedia.org/w/index.php?curid=4508036],
|
||||
alt: "ด้านหลังของแผงวงจรก่อนหน้า ลูกศรสีเขียวชี้ไปยังเซนเซอร์",
|
||||
caption: [ด้านหลังของแผงวงจรที่หันเข้าหากระจกเมื่อติดตั้ง
|
||||
เซ็นเซอร์ไพโรอิเล็กทริกแสดงด้วยลูกศรสีเขียว],
|
||||
)
|
||||
|
||||
#v(2em)
|
||||
|
||||
== รูปแบบลำแสง
|
||||
|
||||
#afigure(
|
||||
image("PIR/Motion_Detector_with_Beam_Pattern.jpg", height: 2in),
|
||||
attr: [AndreasCT, CC BY-SA 4.0, https://commons.wikimedia.org/w/index.php?curid=84066723],
|
||||
attr: [AndreasCT, CC BY-SA 4.0,
|
||||
https://commons.wikimedia.org/w/index.php?curid=84066723],
|
||||
alt: "กราฟิกแสดงลำแสงจำลองการทำงานของเครื่องตรวจจับความเคลื่อนไหว",
|
||||
caption: [เครื่องตรวจจับความเคลื่อนไหวที่มีรูปแบบลำแสงซ้อนทับ ความยาวของลำแสงเป็นตัวชี้วัดความไวของเครื่องตรวจจับในทิศทางนั้น],
|
||||
caption: [เครื่องตรวจจับความเคลื่อนไหวที่มีรูปแบบลำแสงซ้อนทับ
|
||||
ความยาวของลำแสงเป็นตัวชี้วัดความไวของเครื่องตรวจจับในทิศทางนั้น],
|
||||
)
|
||||
|
||||
#i จากการโฟกัส ทำให้มุมมองของเครื่องตรวจจับกลายเป็นรูปแบบลำแสง ภายใต้มุมบางมุม (โซน)\ เซ็นเซอร์ PIR แทบจะไม่ได้รับพลังงานรังสีใด ๆ และภายใต้มุมอื่น ๆ PIR จะได้รับพลังงานอินฟราเรดในปริมาณที่เข้มข้น การแยกนี้ช่วยให้เครื่องตรวจจับความเคลื่อนไหวสามารถแยกแยะระหว่างแสงสว่างที่กว้างและวัตถุที่กำลังเคลื่อนที่ได้
|
||||
#v(2em)
|
||||
|
||||
#i เมื่อบุคคลเดินจากมุมหนึ่ง (ลำแสง) ไปยังอีกมุมหนึ่ง เครื่องตรวจจับจะมองเห็นบุคคลที่กำลังเคลื่อนไหวเป็นระยะ ๆ เท่านั้น ส่งผลให้สัญญาณเซ็นเซอร์เปลี่ยนแปลงอย่างรวดเร็ว ซึ่งระบบอิเล็กทรอนิกส์จะใช้เพื่อส่งสัญญาณเตือนภัยหรือเปิดไฟ ระบบอิเล็กทรอนิกส์จะไม่สนใจสัญญาณที่เปลี่ยนแปลงช้า ๆ
|
||||
#h(8em) จากการโฟกัส ทำให้มุมมองของเครื่องตรวจจับกลายเป็นรูปแบบลำแสง ภายใต้มุมบางมุม (โซน)
|
||||
เซ็นเซอร์ PIR แทบจะไม่ได้รับพลังงานรังสีใด ๆ และภายใต้มุมอื่น ๆ PIR
|
||||
จะได้รับพลังงานอินฟราเรดในปริมาณที่เข้มข้น
|
||||
การแยกนี้ช่วยให้เครื่องตรวจจับความเคลื่อนไหวสามารถแยกแยะระหว่างแสงสว่างที่กว้างและวัตถุที่กำลังเคลื่อนที่ได้
|
||||
|
||||
#i จำนวน รูปร่าง การกระจาย และความไวของโซนเหล่านี้ถูกกำหนดโดยเลนส์และกระจก ผู้ผลิตพยายามอย่างเต็มที่เพื่อสร้างรูปแบบลำแสงความไวที่เหมาะสมที่สุดสำหรับการใช้งานแต่ละประเภท
|
||||
#h(8em) เมื่อบุคคลเดินจากมุมหนึ่ง (ลำแสง) ไปยังอีกมุมหนึ่ง
|
||||
เครื่องตรวจจับจะมองเห็นบุคคลที่กำลังเคลื่อนไหวเป็นระยะ ๆ เท่านั้น
|
||||
ส่งผลให้สัญญาณเซ็นเซอร์เปลี่ยนแปลงอย่างรวดเร็ว
|
||||
ซึ่งระบบอิเล็กทรอนิกส์จะใช้เพื่อส่งสัญญาณเตือนภัยหรือเปิดไฟ
|
||||
ระบบอิเล็กทรอนิกส์จะไม่สนใจสัญญาณที่เปลี่ยนแปลงช้า ๆ
|
||||
|
||||
#h(8em) จำนวน รูปร่าง การกระจาย และความไวของโซนเหล่านี้ถูกกำหนดโดยเลนส์และกระจก
|
||||
ผู้ผลิตพยายามอย่างเต็มที่เพื่อสร้างรูปแบบลำแสงความไวที่เหมาะสมที่สุดสำหรับการใช้งานแต่ละประเภท
|
||||
|
||||
== การใช้งานระบบไฟอัตโนมัติ
|
||||
|
||||
#i เมื่อใช้เป็นส่วนหนึ่งของระบบไฟส่องสว่าง ระบบอิเล็กทรอนิกส์ใน PIR มักจะควบคุมรีเลย์ในตัวที่สามารถสลับแรงดันไฟฟ้าหลักได้ ซึ่งหมายความว่า PIR สามารถตั้งค่าให้เปิดไฟที่เชื่อมต่อกับ PIR เมื่อตรวจพบการเคลื่อนไหวได้ วิธีนี้มักใช้ในสถานการณ์กลางแจ้ง ทั้งเพื่อป้องกันอาชญากร (ไฟรักษาความปลอดภัย) หรือเพื่อการใช้งานจริง เช่น การเปิดไฟประตูหน้าบ้านเพื่อให้คุณหากุญแจเจอในความมืด\ การใช้งานเพิ่มเติมสามารถทำได้ในห้องน้ำสาธารณะ ห้องเตรียมอาหารแบบวอล์กอิน ทางเดิน หรือบริเวณใดก็ตามที่สามารถควบคุมไฟอัตโนมัติได้ วิธีนี้ช่วยประหยัดพลังงานได้ เพราะไฟจะเปิดเฉพาะเมื่อจำเป็นเท่านั้น และผู้ใช้ไม่จำเป็นต้องปิดไฟเมื่อออกจากพื้นที่
|
||||
#h(8em) เมื่อใช้เป็นส่วนหนึ่งของระบบไฟส่องสว่าง ระบบอิเล็กทรอนิกส์ใน PIR
|
||||
มักจะควบคุมรีเลย์ในตัวที่สามารถสลับแรงดันไฟฟ้าหลักได้ ซึ่งหมายความว่า PIR
|
||||
สามารถตั้งค่าให้เปิดไฟที่เชื่อมต่อกับ PIR เมื่อตรวจพบการเคลื่อนไหวได้ วิธีนี้มักใช้ในสถานการณ์กลางแจ้ง
|
||||
ทั้งเพื่อป้องกันอาชญากร (ไฟรักษาความปลอดภัย) หรือเพื่อการใช้งานจริง เช่น
|
||||
การเปิดไฟประตูหน้าบ้านเพื่อให้คุณหากุญแจเจอในความมืด
|
||||
การใช้งานเพิ่มเติมสามารถทำได้ในห้องน้ำสาธารณะ ห้องเตรียมอาหารแบบวอล์กอิน ทางเดิน
|
||||
หรือบริเวณใดก็ตามที่สามารถควบคุมไฟอัตโนมัติได้ วิธีนี้ช่วยประหยัดพลังงานได้
|
||||
เพราะไฟจะเปิดเฉพาะเมื่อจำเป็นเท่านั้น และผู้ใช้ไม่จำเป็นต้องปิดไฟเมื่อออกจากพื้นที่
|
||||
|
||||
== แอปพลิเคชั่นด้านความปลอดภัย
|
||||
|
||||
#i เมื่อใช้เป็นส่วนหนึ่งของระบบรักษาความปลอดภัย วงจรอิเล็กทรอนิกส์ใน PIR มักจะควบคุมรีเลย์ ขนาดเล็ก รีเลย์นี้จะทำหน้าที่เชื่อมต่อวงจรไฟฟ้าผ่านหน้า สัมผัสไฟฟ้าคู่หนึ่งที่เชื่อมต่อกับโซนอินพุตตรวจจับของแผงควบคุมสัญญาณกันขโมยโดยทั่วไประบบจะออกแบบให้หากไม่มีการเคลื่อนไหว หน้าสัมผัสรีเลย์จะปิดอยู่ ซึ่งเรียกว่ารีเลย์แบบ 'ปกติปิด' (NC) หากตรวจพบการเคลื่อนไหว รีเลย์จะเปิดวงจรเพื่อส่งสัญญาณเตือนภัย หรือหากสายไฟถูกตัดการเชื่อมต่อ สัญญาณเตือนภัยก็จะทำงานเช่นกัน
|
||||
#h(8em) เมื่อใช้เป็นส่วนหนึ่งของระบบรักษาความปลอดภัย วงจรอิเล็กทรอนิกส์ใน PIR มักจะควบคุมรีเลย์
|
||||
ขนาดเล็ก รีเลย์นี้จะทำหน้าที่เชื่อมต่อวงจรไฟฟ้าผ่านหน้า
|
||||
สัมผัสไฟฟ้าคู่หนึ่งที่เชื่อมต่อกับโซนอินพุตตรวจจับของแผงควบคุมสัญญาณกันขโมยโดยทั่วไประบบจะออกแบบให้หากไม่มีการเคลื่อนไหว
|
||||
หน้าสัมผัสรีเลย์จะปิดอยู่ ซึ่งเรียกว่ารีเลย์แบบ 'ปกติปิด' (NC) หากตรวจพบการเคลื่อนไหว
|
||||
รีเลย์จะเปิดวงจรเพื่อส่งสัญญาณเตือนภัย หรือหากสายไฟถูกตัดการเชื่อมต่อ สัญญาณเตือนภัยก็จะทำงานเช่นกัน
|
||||
|
||||
== การจัดวาง
|
||||
|
||||
#i ผู้ผลิตแนะนำให้วางผลิตภัณฑ์อย่างระมัดระวังเพื่อป้องกันการแจ้งเตือนที่ผิดพลาด (เช่น การตรวจจับใดๆ ที่ไม่ได้เกิดจากผู้บุกรุก)
|
||||
#h(8em) ผู้ผลิตแนะนำให้วางผลิตภัณฑ์อย่างระมัดระวังเพื่อป้องกันการแจ้งเตือนที่ผิดพลาด (เช่น
|
||||
การตรวจจับใดๆ ที่ไม่ได้เกิดจากผู้บุกรุก)
|
||||
|
||||
#i พวกเขาแนะนำให้ติดตั้ง PIR ในลักษณะที่ PIR ไม่สามารถ "มองเห็น" ออกจากหน้าต่างได้ แม้ว่าความยาวคลื่นของรังสีอินฟราเรดที่ชิปมีความไวต่อแสงจะทะลุผ่านกระจกได้ไม่ดีนัก แต่แหล่งกำเนิดแสงอินฟราเรดที่แรง (เช่น จากไฟหน้ารถยนต์หรือแสงแดด) อาจทำให้เซ็นเซอร์รับภาพเกินพิกัดและทำให้เกิดสัญญาณเตือนภัยผิดพลาดได้ บุคคลที่เคลื่อนไหวอยู่อีกฝั่งของกระจกจะไม่ถูก PID "มองเห็น" ซึ่งอาจเป็นผลดีสำหรับหน้าต่างที่หันหน้าไปทางทางเท้าสาธารณะ หรือเป็นผลเสียสำหรับหน้าต่างในฉากกั้นภายใน
|
||||
#h(8em) พวกเขาแนะนำให้ติดตั้ง PIR ในลักษณะที่ PIR ไม่สามารถ "มองเห็น" ออกจากหน้าต่างได้
|
||||
แม้ว่าความยาวคลื่นของรังสีอินฟราเรดที่ชิปมีความไวต่อแสงจะทะลุผ่านกระจกได้ไม่ดีนัก
|
||||
แต่แหล่งกำเนิดแสงอินฟราเรดที่แรง (เช่น จากไฟหน้ารถยนต์หรือแสงแดด)
|
||||
อาจทำให้เซ็นเซอร์รับภาพเกินพิกัดและทำให้เกิดสัญญาณเตือนภัยผิดพลาดได้
|
||||
บุคคลที่เคลื่อนไหวอยู่อีกฝั่งของกระจกจะไม่ถูก PID "มองเห็น"
|
||||
ซึ่งอาจเป็นผลดีสำหรับหน้าต่างที่หันหน้าไปทางทางเท้าสาธารณะ
|
||||
หรือเป็นผลเสียสำหรับหน้าต่างในฉากกั้นภายใน
|
||||
|
||||
#i ขอแนะนำว่าไม่ควรติดตั้ง PIR ในตำแหน่งที่ ช่องระบายอากาศ HVAC จะเป่าลมร้อนหรือเย็นลงบนพื้นผิวพลาสติกที่ปิดหน้าต่างของตัวบ้าน แม้ว่าอากาศจะมีค่าการแผ่รังสี ต่ำมาก (ปล่อยพลังงานอินฟราเรดในปริมาณน้อยมาก) แต่ลมที่พัดผ่านฝาครอบหน้าต่างพลาสติกอาจทำให้อุณหภูมิของพลาสติกเปลี่ยนแปลงจนทำให้เกิดสัญญาณเตือนที่ผิดพลาดได้
|
||||
#h(8em) ขอแนะนำว่าไม่ควรติดตั้ง PIR ในตำแหน่งที่ ช่องระบายอากาศ HVAC
|
||||
จะเป่าลมร้อนหรือเย็นลงบนพื้นผิวพลาสติกที่ปิดหน้าต่างของตัวบ้าน แม้ว่าอากาศจะมีค่าการแผ่รังสี ต่ำมาก#jb
|
||||
(ปล่อยพลังงานอินฟราเรดในปริมาณน้อยมาก)
|
||||
แต่ลมที่พัดผ่านฝาครอบหน้าต่างพลาสติกอาจทำให้อุณหภูมิของพลาสติกเปลี่ยนแปลงจนทำให้เกิดสัญญาณเตือนที่ผิดพลาดได้
|
||||
|
||||
#i เซ็นเซอร์มักได้รับการออกแบบมาให้ "เพิกเฉย" สัตว์เลี้ยงในบ้าน เช่น สุนัขหรือแมว โดยการตั้งค่าความไวให้สูงขึ้น หรือทำให้แน่ใจว่าพื้นห้องจะไม่อยู่ในโฟกัส
|
||||
#h(8em) เซ็นเซอร์มักได้รับการออกแบบมาให้ "เพิกเฉย" สัตว์เลี้ยงในบ้าน เช่น สุนัขหรือแมว
|
||||
โดยการตั้งค่าความไวให้สูงขึ้น หรือทำให้แน่ใจว่าพื้นห้องจะไม่อยู่ในโฟกัส
|
||||
|
||||
#i เนื่องจากเซ็นเซอร์ PIR มีระยะการทำงานสูงสุด 10 เมตร (30 ฟุต) ดังนั้นการติดตั้งเครื่องตรวจจับเพียงตัวเดียวใกล้ทางเข้าจึงเพียงพอสำหรับห้องที่มีทางเข้าเพียงทางเดียว ระบบรักษาความปลอดภัยที่ใช้ PIR ยังใช้งานได้ดีกับระบบรักษาความปลอดภัยภายนอกอาคารและระบบไฟที่ไวต่อการเคลื่อนไหว ข้อดีอย่างหนึ่งคือใช้พลังงานต่ำ ซึ่งทำให้สามารถใช้พลังงานแสงอาทิตย์ได้
|
||||
#h(8em) เนื่องจากเซ็นเซอร์ PIR มีระยะการทำงานสูงสุด 10 เมตร (30 ฟุต)
|
||||
ดังนั้นการติดตั้งเครื่องตรวจจับเพียงตัวเดียวใกล้ทางเข้าจึงเพียงพอสำหรับห้องที่มีทางเข้าเพียงทางเดียว
|
||||
ระบบรักษาความปลอดภัยที่ใช้ PIR
|
||||
ยังใช้งานได้ดีกับระบบรักษาความปลอดภัยภายนอกอาคารและระบบไฟที่ไวต่อการเคลื่อนไหว
|
||||
ข้อดีอย่างหนึ่งคือใช้พลังงานต่ำ ซึ่งทำให้สามารถใช้พลังงานแสงอาทิตย์ได้
|
||||
|
||||
== เทอร์โมมิเตอร์แบบควบคุมระยะไกลด้วย PIR
|
||||
|
||||
#i มีการออกแบบวงจร PIR ที่ใช้วัดอุณหภูมิของวัตถุที่อยู่ห่างไกลในวงจรดังกล่าว จะใช้เอาต์พุต PIR แบบไม่มีค่าความแตกต่าง สัญญาณเอาต์พุตจะถูกประเมินตามการสอบเทียบสเปกตรัม IR ของสสารชนิดเฉพาะที่ต้องการตรวจวัด ด้วยวิธีนี้ การวัดอุณหภูมิจากระยะไกลจึงค่อนข้างแม่นยำและแม่นยำ หากไม่มีการสอบเทียบกับชนิดของวัสดุที่ตรวจวัด อุปกรณ์เทอร์โมมิเตอร์ PIR จะสามารถวัดการเปลี่ยนแปลงของการแผ่รังสี IR ซึ่งสอดคล้องกับการเปลี่ยนแปลงของอุณหภูมิโดยตรง แต่ไม่สามารถคำนวณค่าอุณหภูมิที่แท้จริงได้
|
||||
#h(8em) มีการออกแบบวงจร PIR ที่ใช้วัดอุณหภูมิของวัตถุที่อยู่ห่างไกลในวงจรดังกล่าว#jb จะใช้เอาต์พุต
|
||||
PIR แบบไม่มีค่าความแตกต่าง สัญญาณเอาต์พุตจะถูกประเมินตามการสอบเทียบ#jb สเปกตรัม IR
|
||||
ของสสารชนิดเฉพาะที่ต้องการตรวจวัด ด้วยวิธีนี้ การวัดอุณหภูมิจากระยะไกลจึงค่อนข้างแม่นยำและแม่นยำ
|
||||
หากไม่มีการสอบเทียบกับชนิดของวัสดุที่ตรวจวัด อุปกรณ์เทอร์โมมิเตอร์ PIR
|
||||
จะสามารถวัดการเปลี่ยนแปลงของการแผ่รังสี IR ซึ่งสอดคล้องกับการเปลี่ยนแปลงของอุณหภูมิโดยตรง
|
||||
แต่ไม่สามารถคำนวณค่าอุณหภูมิที่แท้จริงได้
|
||||
|
||||
@@ -3,16 +3,42 @@
|
||||
|
||||
= เซนเซอร์ (Sensors)
|
||||
|
||||
#i โดยทั่วไปแล้ว เซนเซอร์จะถูกนิยามว่าเป็นอุปกรณ์ที่รับและตอบสนองต่อสัญญาณหรือสิ่งเร้าสิ่งเร้าคือปริมาณ คุณสมบัติ หรือสภาวะที่ถูกตรวจจับและแปลงเป็นสัญญาณไฟฟ้า
|
||||
#h(1.7em) โดยทั่วไปแล้ว เซนเซอร์จะถูกนิยามว่าเป็นอุปกรณ์ที่รับและตอบสนองต่อสัญญาณหรือสิ่งเร้าสิ่งเร้าคือปริมาณ
|
||||
คุณสมบัติ หรือสภาวะที่ถูกตรวจจับและแปลงเป็นสัญญาณไฟฟ้า
|
||||
|
||||
#i ในความหมายกว้างที่สุด เซนเซอร์คืออุปกรณ์ โมดูล เครื่องจักร หรือระบบย่อยที่ตรวจจับเหตุการณ์หรือการเปลี่ยนแปลงในสภาพแวดล้อม และส่งข้อมูลไปยังอุปกรณ์อิเล็กทรอนิกส์อื่นๆ ซึ่งส่วนใหญ่มักจะเป็นหน่วยประมวลผลของคอมพิวเตอร์
|
||||
#h(1.7em) ในความหมายกว้างที่สุด เซนเซอร์คืออุปกรณ์ โมดูล เครื่องจักร
|
||||
หรือระบบย่อยที่ตรวจจับเหตุการณ์หรือการเปลี่ยนแปลงในสภาพแวดล้อม
|
||||
และส่งข้อมูลไปยังอุปกรณ์อิเล็กทรอนิกส์อื่นๆ ซึ่งส่วนใหญ่มักจะเป็นหน่วยประมวลผลของคอมพิวเตอร์
|
||||
|
||||
#i เซ็นเซอร์ถูกนำมาใช้ในสิ่งของในชีวิตประจำวัน เช่น ปุ่มลิฟต์แบบสัมผัส (เซ็นเซอร์สัมผัส) และโคมไฟที่หรี่หรือสว่างขึ้นโดยการสัมผัสที่ฐาน และในแอปพลิเคชันมากมายนับไม่ถ้วนซึ่งคนส่วนใหญ่ไม่เคยตระหนักถึง ด้วยความก้าวหน้าในด้านไมโครแมชชีนเนอรี่ และแพลตฟอร์ม ไมโครคอนโทรลเลอร์ที่ใช้งานง่ายการใช้งานเซ็นเซอร์จึงขยายออกไปนอกเหนือจากสาขาแบบดั้งเดิมของการวัดอุณหภูมิ ความดัน และการไหลตัวอย่างเช่น ไปสู่เซ็นเซอร์ MARG
|
||||
#h(1.7em) เซ็นเซอร์ถูกนำมาใช้ในสิ่งของในชีวิตประจำวัน เช่น ปุ่มลิฟต์แบบสัมผัส (เซ็นเซอร์สัมผัส)
|
||||
และโคมไฟที่หรี่หรือสว่างขึ้นโดยการสัมผัสที่ฐาน
|
||||
และในแอปพลิเคชันมากมายนับไม่ถ้วนซึ่งคนส่วนใหญ่ไม่เคยตระหนักถึง
|
||||
ด้วยความก้าวหน้าในด้านไมโครแมชชีนเนอรี่ และแพลตฟอร์ม
|
||||
ไมโครคอนโทรลเลอร์ที่ใช้งานง่ายการใช้งานเซ็นเซอร์จึงขยายออกไปนอกเหนือจากสาขาแบบดั้งเดิมของการวัดอุณหภูมิ
|
||||
ความดัน และการไหลตัวอย่างเช่น ไปสู่เซ็นเซอร์ MARG
|
||||
|
||||
#i เซ็นเซอร์แบบอนาล็อก เช่นโพเทนชิโอมิเตอร์และตัวต้านทานรับแรงยังคงมีการใช้งานอย่างแพร่หลาย การใช้งานของเซ็นเซอร์เหล่านี้รวมถึงการผลิตและเครื่องจักร เครื่องบินและอวกาศ รถยนต์ การแพทย์ หุ่นยนต์และอีกหลายแง่มุมในชีวิตประจำวันของเรา นอกจากนี้ยังมีเซ็นเซอร์อื่นๆ อีกมากมายที่ใช้วัดคุณสมบัติทางเคมีและกายภาพของวัสดุ รวมถึงเซ็นเซอร์แบบออปติคอลสำหรับการวัดดัชนีหักเห เซ็นเซอร์แบบสั่นสะเทือนสำหรับการวัดความหนืดของของเหลว และเซ็นเซอร์ทางเคมีไฟฟ้าสำหรับการตรวจสอบค่า pH ของของเหลว
|
||||
#h(1.7em) เซ็นเซอร์แบบอนาล็อก เช่นโพเทนชิโอมิเตอร์และตัวต้านทานรับแรงยังคงมีการใช้งานอย่างแพร่หลาย
|
||||
การใช้งานของเซ็นเซอร์เหล่านี้รวมถึงการผลิตและเครื่องจักร เครื่องบินและอวกาศ รถยนต์ การแพทย์
|
||||
หุ่นยนต์และอีกหลายแง่มุมในชีวิตประจำวันของเรา นอกจากนี้ยังมีเซ็นเซอร์อื่นๆ
|
||||
อีกมากมายที่ใช้วัดคุณสมบัติทางเคมีและกายภาพของวัสดุ รวมถึงเซ็นเซอร์แบบออปติคอลสำหรับการวัดดัชนีหักเห
|
||||
เซ็นเซอร์แบบสั่นสะเทือนสำหรับการวัดความหนืดของของเหลว
|
||||
และเซ็นเซอร์ทางเคมีไฟฟ้าสำหรับการตรวจสอบค่า pH ของของเหลว
|
||||
|
||||
#i ความไวของเซนเซอร์บ่งชี้ว่าเอาต์พุตเปลี่ยนแปลงไปมากน้อยเพียงใดเมื่อปริมาณอินพุตที่วัดเปลี่ยนแปลง ตัวอย่างเช่น หากปรอทในเทอร์โมมิเตอร์เคลื่อนที่ 1 ซม. เมื่ออุณหภูมิเปลี่ยนแปลง 1 °C ความไวของมันคือ 1 ซม./°C (โดยพื้นฐานแล้วคือความชัน dy/dx โดยสมมติว่ามีลักษณะเชิงเส้น) เซนเซอร์บางชนิดอาจส่งผลต่อสิ่งที่วัดได้เช่นกัน ตัวอย่างเช่น เทอร์โมมิเตอร์วัดอุณหภูมิห้องที่เสียบลงในถ้วยของเหลวร้อนจะทำให้ของเหลวเย็นลงในขณะที่ของเหลวทำให้เทอร์โมมิเตอร์ร้อนขึ้น โดยทั่วไปเซนเซอร์ได้รับการออกแบบให้มีผลกระทบต่อสิ่งที่วัดน้อยที่สุด การทำให้เซนเซอร์มีขนาดเล็กลงมักจะช่วยปรับปรุงสิ่งนี้และอาจนำมาซึ่งข้อดีอื่นๆ
|
||||
#h(1.7em) ความไวของเซนเซอร์บ่งชี้ว่าเอาต์พุตเปลี่ยนแปลงไปมากน้อยเพียงใดเมื่อปริมาณอินพุตที่วัดเปลี่ยนแปลง
|
||||
ตัวอย่างเช่น หากปรอทในเทอร์โมมิเตอร์เคลื่อนที่ 1 ซม. เมื่ออุณหภูมิเปลี่ยนแปลง#jb 1 °C
|
||||
ความไวของมันคือ 1 ซม./°C (โดยพื้นฐานแล้วคือความชัน dy/dx โดยสมมติว่ามีลักษณะเชิงเส้น)#jb
|
||||
เซนเซอร์บางชนิดอาจส่งผลต่อสิ่งที่วัดได้เช่นกัน ตัวอย่างเช่น
|
||||
เทอร์โมมิเตอร์วัดอุณหภูมิห้องที่เสียบลงในถ้วยของเหลวร้อนจะทำให้ของเหลวเย็นลงในขณะที่ของเหลวทำให้เทอร์โมมิเตอร์ร้อนขึ้น
|
||||
โดยทั่วไปเซนเซอร์ได้รับการออกแบบให้มีผลกระทบต่อสิ่งที่วัดน้อยที่สุด
|
||||
การทำให้เซนเซอร์มีขนาดเล็กลงมักจะช่วยปรับปรุงสิ่งนี้และอาจนำมาซึ่งข้อดีอื่นๆ
|
||||
|
||||
#i ความก้าวหน้าทางเทคโนโลยีทำให้สามารถผลิตเซ็นเซอร์ได้มากขึ้นเรื่อยๆ ในระดับจุลภาคเช่น ไมโครเซ็นเซอร์โดยใช้ เทคโนโลยี MEMSในกรณีส่วนใหญ่ ไมโครเซ็นเซอร์สามารถวัดได้เร็วกว่าและมีความไวสูงกว่าเมื่อเทียบกับวิธีการแบบมหภาคเนื่องจากความต้องการข้อมูลที่รวดเร็ว ราคาไม่แพง และเชื่อถือได้เพิ่มมากขึ้นในโลกปัจจุบัน เซ็นเซอร์แบบใช้แล้วทิ้ง ซึ่งเป็นอุปกรณ์ราคาถูกและใช้งานง่ายสำหรับการตรวจสอบระยะสั้นหรือการวัดแบบครั้งเดียว จึงได้รับความสำคัญเพิ่มมากขึ้น การใช้เซ็นเซอร์ประเภทนี้ทำให้ทุกคนสามารถรับข้อมูลการวิเคราะห์ที่สำคัญได้ทุกที่ ทุกเวลา โดยไม่จำเป็นต้องปรับเทียบใหม่และไม่ต้องกังวลเรื่องการปนเปื้อน
|
||||
#h(1.7em) ความก้าวหน้าทางเทคโนโลยีทำให้สามารถผลิตเซ็นเซอร์ได้มากขึ้นเรื่อย ๆ ในระดับจุลภาคเช่น
|
||||
ไมโครเซ็นเซอร์โดยใช้เทคโนโลยี MEMS ในกรณีส่วนใหญ่
|
||||
ไมโครเซ็นเซอร์สามารถวัดได้เร็วกว่าและมีความไวสูงกว่าเมื่อเทียบกับวิธีการแบบมหภาคเนื่องจากความต้องการข้อมูลที่รวดเร็ว
|
||||
ราคาไม่แพง#jb และเชื่อถือได้เพิ่มมากขึ้นในโลกปัจจุบัน เซ็นเซอร์แบบใช้แล้วทิ้ง
|
||||
ซึ่งเป็นอุปกรณ์ราคาถูกและใช้งานง่ายสำหรับการตรวจสอบระยะสั้นหรือการวัดแบบครั้งเดียว
|
||||
จึงได้รับความสำคัญเพิ่มมากขึ้น
|
||||
การใช้เซ็นเซอร์ประเภทนี้ทำให้ทุกคนสามารถรับข้อมูลการวิเคราะห์ที่สำคัญได้ทุกที่ ทุกเวลา
|
||||
โดยไม่จำเป็นต้องปรับเทียบใหม่และไม่ต้องกังวลเรื่องการปนเปื้อน
|
||||
|
||||
#include "PIR.typ"
|
||||
|
||||
@@ -1,53 +1,141 @@
|
||||
#import "../PageTemplate.typ": i
|
||||
#import "../PageTemplate.typ": *
|
||||
#set list(marker: ([•], [○], [■]))
|
||||
|
||||
= เกณฑ์วิธีความมั่นคงของชั้นขนส่ง (Transport Layer Security; TLS)
|
||||
|
||||
#i
|
||||
เกณฑ์วิธีความมั่นคงของชั้นขนส่ง (Transport Layer Security; TLS) เป็นโปรโตคอลการเข้ารหัสที่ออกแบบมาเพื่อรักษาความปลอดภัยการสื่อสารบนเครือข่ายคอมพิวเตอร์เช่นอินเทอร์เน็ตโปรโตคอลนี้ถูกใช้อย่างแพร่หลายในแอปพลิเคชันต่างๆเช่นอีเมลการส่งข้อความโต้ตอบแบบทันทีและบริการเสียงผ่าน IP แต่การใช้งานเพื่อรักษาความปลอดภัย HTTPS ยังคงเป็นที่เปิดเผยต่อสาธารณะมากที่สุด
|
||||
#h(1.7em)
|
||||
เกณฑ์วิธีความมั่นคงของชั้นขนส่ง (Transport Layer Security; TLS)
|
||||
เป็นโปรโตคอลการเข้ารหัสที่ออกแบบมาเพื่อรักษาความปลอดภัยการสื่อสารบนเครือข่ายคอมพิวเตอร์เช่นอินเทอร์เน็ตโปรโตคอลนี้ถูกใช้อย่างแพร่หลายในแอปพลิเคชันต่างๆเช่นอีเมลการส่งข้อความโต้ตอบแบบทันทีและบริการเสียงผ่าน
|
||||
IP แต่การใช้งานเพื่อรักษาความปลอดภัย HTTPS ยังคงเป็นที่เปิดเผยต่อสาธารณะมากที่สุด
|
||||
|
||||
#i โปรโตคอล TLS มีวัตถุประสงค์หลักเพื่อรักษาความปลอดภัย รวมถึงความเป็นส่วนตัว (ความลับ) ความสมบูรณ์ และความถูกต้อง ผ่านการใช้การเข้ารหัสเช่น การใช้ใบรับรองระหว่างแอปพลิเคชันคอมพิวเตอร์ที่สื่อสารกันตั้งแต่สองแอปพลิเคชันขึ้นไป โปรโตคอลนี้ทำงานในเลเยอร์การนำเสนอและประกอบด้วยสองชั้น ได้แก่ ระเบียน TLS และโปรโตคอล TLS handshake
|
||||
#h(1.7em) โปรโตคอล TLS มีวัตถุประสงค์หลักเพื่อรักษาความปลอดภัย รวมถึงความเป็นส่วนตัว (ความลับ)
|
||||
ความสมบูรณ์ และความถูกต้อง ผ่านการใช้การเข้ารหัสเช่น
|
||||
การใช้ใบรับรองระหว่างแอปพลิเคชันคอมพิวเตอร์ที่สื่อสารกันตั้งแต่สองแอปพลิเคชันขึ้นไป
|
||||
โปรโตคอลนี้ทำงานในเลเยอร์การนำเสนอและประกอบด้วยสองชั้น ได้แก่ ระเบียน TLS และโปรโตคอล TLS
|
||||
handshake
|
||||
|
||||
#i Datagram Transport Layer Security (DTLS) ซึ่งเป็นโปรโตคอลการสื่อสารที่เกี่ยวข้องอย่างใกล้ชิดมอบความปลอดภัยให้กับ แอปพลิเคชันที่ใช้ ดาต้าแกรมในงานเขียนทางเทคนิค มักพบการอ้างอิงถึง "(D)TLS" เมื่อใช้กับทั้งสองเวอร์ชัน
|
||||
#h(1.7em) Datagram Transport Layer Security (DTLS)
|
||||
ซึ่งเป็นโปรโตคอลการสื่อสารที่เกี่ยวข้องอย่างใกล้ชิดมอบความปลอดภัยให้กับ แอปพลิเคชันที่ใช้
|
||||
ดาต้าแกรมในงานเขียนทางเทคนิค มักพบการอ้างอิงถึง "(D)TLS" เมื่อใช้กับทั้งสองเวอร์ชัน
|
||||
|
||||
#i TLS เป็นมาตรฐานที่ได้รับการเสนอโดย Internet Engineering Task Force (IETF) ซึ่งกำหนดขึ้นครั้งแรกในปี 1999 และเวอร์ชันปัจจุบันคือ TLS 1.3 ซึ่งกำหนดขึ้นในเดือนสิงหาคม 2018 TLS สร้างขึ้นจาก ข้อกำหนด SSL (Secure Sockets Layer) ที่ไม่รองรับอีกต่อไป (1994, 1995, 1996) ซึ่งพัฒนาโดย Netscape Communications เพื่อเพิ่มโปรโตคอล HTTPS ลงในเว็บเบราว์เซอร์ Netscape Navigator
|
||||
#h(1.7em) TLS เป็นมาตรฐานที่ได้รับการเสนอโดย Internet Engineering Task Force (IETF)
|
||||
ซึ่งกำหนดขึ้นครั้งแรกในปี 1999 และเวอร์ชันปัจจุบันคือ TLS 1.3 ซึ่งกำหนดขึ้นในเดือนสิงหาคม 2018 TLS
|
||||
สร้างขึ้นจาก ข้อกำหนด SSL (Secure Sockets Layer) ที่ไม่รองรับอีกต่อไป (1994, 1995, 1996)
|
||||
ซึ่งพัฒนาโดย Netscape Communications เพื่อเพิ่มโปรโตคอล HTTPS ลงในเว็บเบราว์เซอร์ Netscape
|
||||
Navigator
|
||||
|
||||
== คำอธิบาย
|
||||
#i
|
||||
เนื่องจากแอปพลิเคชันสามารถสื่อสารได้ทั้งแบบมีหรือไม่มี TLS (หรือ SSL) จึงจำเป็นที่ไคลเอนต์จะต้องร้องขอให้เซิร์ฟเวอร์ตั้งค่าการเชื่อมต่อ TLS หนึ่งในวิธีหลักในการทำเช่นนี้คือการใช้หมายเลขพอร์ต อื่น สำหรับการเชื่อมต่อ TLS โดยทั่วไปแล้ว พอร์ต 80 จะใช้สำหรับ การรับส่งข้อมูล HTTP ที่ไม่ได้เข้ารหัส ในขณะที่พอร์ต 443 เป็นพอร์ตทั่วไปที่ใช้สำหรับ การรับส่งข้อมูล HTTPS ที่เข้ารหัส อีกกลไกหนึ่งคือการสร้างคำขอ STARTTLS เฉพาะโปรโตคอลไปยังเซิร์ฟเวอร์เพื่อสลับการเชื่อมต่อกับ TLS ตัวอย่างเช่น เมื่อใช้โปรโตคอลอีเมลและข่าวสารบางอย่าง
|
||||
#iii
|
||||
เนื่องจากแอปพลิเคชันสามารถสื่อสารได้ทั้งแบบมีหรือไม่มี TLS (หรือ SSL)
|
||||
จึงจำเป็นที่ไคลเอนต์จะต้องร้องขอให้เซิร์ฟเวอร์ตั้งค่าการเชื่อมต่อ TLS
|
||||
หนึ่งในวิธีหลักในการทำเช่นนี้คือการใช้หมายเลขพอร์ต อื่น สำหรับการเชื่อมต่อ TLS โดยทั่วไปแล้ว พอร์ต 80
|
||||
จะใช้สำหรับ การรับส่งข้อมูล HTTP ที่ไม่ได้เข้ารหัส ในขณะที่พอร์ต 443 เป็นพอร์ตทั่วไปที่ใช้สำหรับ
|
||||
การรับส่งข้อมูล HTTPS ที่เข้ารหัส อีกกลไกหนึ่งคือการสร้างคำขอ STARTTLS
|
||||
เฉพาะโปรโตคอลไปยังเซิร์ฟเวอร์เพื่อสลับการเชื่อมต่อกับ TLS ตัวอย่างเช่น
|
||||
เมื่อใช้โปรโตคอลอีเมลและข่าวสารบางอย่าง
|
||||
|
||||
#i เมื่อไคลเอนต์และเซิร์ฟเวอร์ตกลงที่จะใช้ TLS แล้ว พวกเขาจะเจรจา การเชื่อมต่อ แบบมีสถานะโดยใช้ขั้นตอนการจับมือ (ดูการจับมือ TLS) โปรโตคอลใช้การจับมือกับรหัสแบบอสมมาตรเพื่อกำหนดค่าการเข้ารหัสไม่เพียงเท่านั้น แต่ยังรวมถึงคีย์ที่ใช้ร่วมกันเฉพาะเซสชัน ซึ่งการสื่อสารต่อไปจะถูกเข้ารหัสโดยใช้รหัสแบบสมมาตรในระหว่างการจับมือนี้ ไคลเอนต์และเซิร์ฟเวอร์จะตกลงกันเกี่ยวกับพารามิเตอร์ต่างๆ ที่ใช้สร้างความปลอดภัยของการเชื่อมต่อ:
|
||||
#iii เมื่อไคลเอนต์และเซิร์ฟเวอร์ตกลงที่จะใช้ TLS แล้ว พวกเขาจะเจรจา การเชื่อมต่อ
|
||||
แบบมีสถานะโดยใช้ขั้นตอนการจับมือ (ดูการจับมือ TLS)
|
||||
โปรโตคอลใช้การจับมือกับรหัสแบบอสมมาตรเพื่อกำหนดค่าการเข้ารหัสไม่เพียงเท่านั้น
|
||||
แต่ยังรวมถึงคีย์ที่ใช้ร่วมกันเฉพาะเซสชัน
|
||||
ซึ่งการสื่อสารต่อไปจะถูกเข้ารหัสโดยใช้รหัสแบบสมมาตรในระหว่างการจับมือนี้
|
||||
ไคลเอนต์และเซิร์ฟเวอร์จะตกลงกันเกี่ยวกับพารามิเตอร์ต่างๆ ที่ใช้สร้างความปลอดภัยของการเชื่อมต่อ
|
||||
|
||||
- การจับมือเริ่มต้นเมื่อไคลเอนต์เชื่อมต่อกับเซิร์ฟเวอร์ที่เปิดใช้งาน TLS เพื่อขอการเชื่อมต่อที่ปลอดภัยและไคลเอนต์แสดงรายการชุดรหัสที่รองรับ (รหัสและฟังก์ชันแฮช)
|
||||
- จากรายการนี้ เซิร์ฟเวอร์จะเลือกฟังก์ชันรหัสและแฮชที่รองรับ และแจ้งให้ไคลเอนต์ทราบถึงการตัดสินใจ
|
||||
- โดยปกติแล้วเซิร์ฟเวอร์จะระบุตัวตนในรูปแบบของใบรับรองดิจิทัลใบรับรองประกอบด้วยชื่อเซิร์ฟเวอร์ผู้ให้บริการออกใบรับรอง (CA) ที่เชื่อถือได้ซึ่งรับรองความถูกต้องของใบรับรอง และคีย์การเข้ารหัสสาธารณะของเซิร์ฟเวอร์
|
||||
- ลูกค้าต้องยืนยันความถูกต้องของใบรับรองก่อนดำเนินการต่อ
|
||||
- ในการสร้างคีย์เซสชันที่ใช้สำหรับการเชื่อมต่อที่ปลอดภัย ไคลเอนต์จะต้องทำดังนี้:
|
||||
- เข้ารหัสตัวเลขสุ่ม (PreMasterSecret) ด้วยคีย์สาธารณะของเซิร์ฟเวอร์และส่งผลลัพธ์ไปยังเซิร์ฟเวอร์ (ซึ่งเฉพาะเซิร์ฟเวอร์เท่านั้นที่จะสามารถถอดรหัสด้วยคีย์ส่วนตัว) จากนั้นทั้งสองฝ่ายใช้ตัวเลขสุ่มเพื่อสร้างคีย์เซสชันเฉพาะสำหรับการเข้ารหัสและถอดรหัสข้อมูลในระหว่างเซสชันในภายหลังหรือ
|
||||
- ใช้การแลกเปลี่ยนคีย์ Diffie–Hellman (หรือรูปแบบ DH ที่เป็นเส้นโค้งวงรี) เพื่อสร้างคีย์เซสชันแบบสุ่มและไม่ซ้ำกันอย่างปลอดภัยสำหรับการเข้ารหัสและถอดรหัส ซึ่งมีคุณสมบัติเพิ่มเติมของการปกปิดแบบส่งต่อ : หากคีย์ส่วนตัวของเซิร์ฟเวอร์ถูกเปิดเผยในอนาคต จะไม่สามารถใช้คีย์นั้นเพื่อถอดรหัสเซสชันปัจจุบันได้ แม้ว่าเซสชันนั้นจะถูกดักจับและบันทึกโดยบุคคลที่สามก็ตาม
|
||||
#[
|
||||
#set enum(indent: 4.1em)
|
||||
1. การจับมือเริ่มต้นเมื่อไคลเอนต์เชื่อมต่อกับเซิร์ฟเวอร์ที่เปิดใช้งาน TLS
|
||||
เพื่อขอการเชื่อมต่อที่ปลอดภัยและไคลเอนต์แสดงรายการชุดรหัสที่รองรับ (รหัสและฟังก์ชันแฮช)
|
||||
2. จากรายการนี้ เซิร์ฟเวอร์จะเลือกฟังก์ชันรหัสและแฮชที่รองรับ
|
||||
และแจ้งให้ไคลเอนต์ทราบถึงการตัดสินใจ
|
||||
3. โดยปกติแล้วเซิร์ฟเวอร์จะระบุตัวตนในรูปแบบของใบรับรองดิจิทัลใบรับรองประกอบด้วยชื่อเซิร์ฟเวอร์ผู้ให้บริการออกใบรับรอง
|
||||
(CA) ที่เชื่อถือได้ซึ่งรับรองความถูกต้องของใบรับรอง และคีย์การเข้ารหัสสาธารณะของเซิร์ฟเวอร์
|
||||
4. ลูกค้าต้องยืนยันความถูกต้องของใบรับรองก่อนดำเนินการต่อ
|
||||
5. ในการสร้างคีย์เซสชันที่ใช้สำหรับการเชื่อมต่อที่ปลอดภัย ไคลเอนต์จะต้องทำดังนี้
|
||||
|
||||
#i การดำเนินการนี้จะสิ้นสุดการจับมือและเริ่มการเชื่อมต่อที่ปลอดภัยซึ่งจะถูกเข้ารหัสและถอดรหัสด้วยคีย์เซสชันจนกว่าการเชื่อมต่อจะสิ้นสุดลงหากขั้นตอนใดขั้นตอนหนึ่งข้างต้นล้มเหลวการจับมือ TLS จะล้มเหลวและการเชื่อมต่อจะไม่ถูกสร้างขึ้น
|
||||
#listy(
|
||||
indent: 5.4em,
|
||||
numbering: thai-numbering,
|
||||
[เข้ารหัสตัวเลขสุ่ม (PreMasterSecret)
|
||||
ด้วยคีย์สาธารณะของเซิร์ฟเวอร์และส่งผลลัพธ์ไปยังเซิร์ฟเวอร์
|
||||
(ซึ่งเฉพาะเซิร์ฟเวอร์เท่านั้นที่จะสามารถถอดรหัสด้วยคีย์ส่วนตัว)
|
||||
จากนั้นทั้งสองฝ่ายใช้ตัวเลขสุ่มเพื่อสร้างคีย์เซสชันเฉพาะสำหรับการเข้ารหัสและถอดรหัสข้อมูลในระหว่างเซสชันในภายหลังหรือ],
|
||||
[ใช้การแลกเปลี่ยนคีย์ Diffie--Hellman (หรือรูปแบบ DH ที่เป็นเส้นโค้งวงรี)
|
||||
เพื่อสร้างคีย์เซสชันแบบสุ่มและไม่ซ้ำกันอย่างปลอดภัยสำหรับการเข้ารหัสและถอดรหัส
|
||||
ซึ่งมีคุณสมบัติเพิ่มเติมของการปกปิดแบบส่งต่อ โดยหากคีย์ส่วนตัวของเซิร์ฟเวอร์ถูกเปิดเผยในอนาคต
|
||||
จะไม่สามารถใช้คีย์นั้นเพื่อถอดรหัสเซสชันปัจจุบันได้
|
||||
แม้ว่าเซสชันนั้นจะถูกดักจับและบันทึกโดยบุคคลที่สามก็ตาม],
|
||||
)
|
||||
]
|
||||
|
||||
#i TLS และ SSL ไม่สามารถจัดวางได้อย่างลงตัวในเลเยอร์ใดเลเยอร์หนึ่งของแบบจำลอง OSI หรือแบบจำลอง TCP/IP TLS ทำงาน "บนโปรโตคอลการขนส่งที่เชื่อถือได้ (เช่น TCP)" ซึ่งหมายความว่ามันอยู่เหนือเลเยอร์การขนส่งมันทำหน้าที่เข้ารหัสให้กับเลเยอร์ที่สูงกว่า ซึ่งโดยปกติแล้วเป็นหน้าที่ของเลเยอร์การนำเสนออย่างไรก็ตาม โดยทั่วไปแอปพลิเคชันจะใช้ TLS เหมือนกับเป็นเลเยอร์การขนส่งแม้ว่าแอปพลิเคชันที่ใช้ TLS จะต้องควบคุมการเริ่มต้นการจับมือ TLS และการจัดการใบรับรองการตรวจสอบสิทธิ์ที่แลกเปลี่ยนกัน
|
||||
#iii
|
||||
การดำเนินการนี้จะสิ้นสุดการจับมือและเริ่มการเชื่อมต่อที่ปลอดภัยซึ่งจะถูกเข้ารหัสและถอดรหัสด้วยคีย์เซสชันจนกว่าการเชื่อมต่อจะสิ้นสุดลงหากขั้นตอนใดขั้นตอนหนึ่งข้างต้นล้มเหลวการจับมือ
|
||||
TLS จะล้มเหลวและการเชื่อมต่อจะไม่ถูกสร้างขึ้น
|
||||
|
||||
#i เมื่อได้รับการรักษาความปลอดภัยโดย TLS การเชื่อมต่อระหว่างไคลเอนต์ (เช่น เว็บเบราว์เซอร์)\ และเซิร์ฟเวอร์ (เช่น wikipedia.org) จะมีคุณสมบัติทั้งหมดดังต่อไปนี้
|
||||
#iii TLS และ SSL ไม่สามารถจัดวางได้อย่างลงตัวในเลเยอร์ใดเลเยอร์หนึ่งของแบบจำลอง OSI
|
||||
หรือแบบจำลอง TCP/IP TLS ทำงาน "บนโปรโตคอลการขนส่งที่เชื่อถือได้ (เช่น TCP)"
|
||||
ซึ่งหมายความว่ามันอยู่เหนือเลเยอร์การขนส่งมันทำหน้าที่เข้ารหัสให้กับเลเยอร์ที่สูงกว่า
|
||||
ซึ่งโดยปกติแล้วเป็นหน้าที่ของเลเยอร์การนำเสนออย่างไรก็ตาม โดยทั่วไปแอปพลิเคชันจะใช้ TLS
|
||||
เหมือนกับเป็นเลเยอร์การขนส่งแม้ว่าแอปพลิเคชันที่ใช้ TLS จะต้องควบคุมการเริ่มต้นการจับมือ TLS
|
||||
และการจัดการใบรับรองการตรวจสอบสิทธิ์ที่แลกเปลี่ยนกัน
|
||||
|
||||
- การเชื่อมต่อเป็นแบบส่วนตัว (หรือมีความลับ) เนื่องจาก มีการใช้ อัลกอริทึมคีย์แบบสมมาตรในการเข้ารหัสข้อมูลที่ส่ง คีย์สำหรับการเข้ารหัสแบบสมมาตรนี้จะถูกสร้างขึ้นอย่างเฉพาะเจาะจงสำหรับแต่ละการเชื่อมต่อ และอิงจากความลับร่วมที่เจรจากันไว้เมื่อเริ่มต้นเซสชัน เซิร์ฟเวอร์และไคลเอ็นต์จะเจรจารายละเอียดเกี่ยวกับอัลกอริทึมการเข้ารหัสและคีย์การเข้ารหัสที่จะใช้ก่อนที่จะส่งข้อมูลไบต์แรก (ดูด้านล่าง) การเจรจาความลับร่วมนั้นทั้งปลอดภัย (ความลับที่เจรจากันไว้จะไม่สามารถเข้าถึงได้โดยผู้ดักฟังและไม่สามารถได้รับ แม้แต่โดยผู้โจมตีที่วางตัวเองอยู่ตรงกลางการเชื่อมต่อ) และเชื่อถือได้ (ไม่มีผู้โจมตีคนใดสามารถแก้ไขการสื่อสารระหว่างการเจรจาโดยไม่ถูกตรวจพบ)
|
||||
- การยืนยันตัวตนของฝ่ายที่สื่อสารสามารถยืนยันได้โดยใช้การเข้ารหัสด้วยคีย์สาธารณะการยืนยันตัวตนนี้จำเป็นสำหรับเซิร์ฟเวอร์และเป็นทางเลือกสำหรับไคลเอนต์
|
||||
- การเชื่อมต่อมีความน่าเชื่อถือ (หรือมีความสมบูรณ์) เนื่องจากข้อความแต่ละข้อความที่ส่งออกจะมีการตรวจสอบความสมบูรณ์ของข้อความโดยใช้รหัสยืนยันข้อความเพื่อป้องกันการสูญหายหรือการเปลี่ยนแปลงข้อมูลที่ไม่ถูกตรวจพบระหว่างการส่งข้อมูล
|
||||
#iii เมื่อได้รับการรักษาความปลอดภัยโดย TLS การเชื่อมต่อระหว่างไคลเอนต์ (เช่น เว็บเบราว์เซอร์)
|
||||
และเซิร์ฟเวอร์ (เช่น wikipedia.org) จะมีคุณสมบัติทั้งหมดดังต่อไปนี้
|
||||
|
||||
#i TLS รองรับวิธีการที่หลากหลายสำหรับการแลกเปลี่ยนคีย์ การเข้ารหัสข้อมูล และการตรวจสอบความถูกต้องของข้อความ ดังนั้น การกำหนดค่า TLS อย่างปลอดภัยจึงเกี่ยวข้องกับพารามิเตอร์ที่กำหนดค่าได้มากมาย และตัวเลือกทั้งหมดไม่ได้มีคุณสมบัติที่เกี่ยวข้องกับความเป็นส่วนตัวทั้งหมดที่อธิบายไว้ในรายการด้านบน (ดูตารางด้านล่าง การแลกเปลี่ยนคีย์ ความปลอดภัยของการเข้ารหัสและความสมบูรณ์ของข้อมูล)
|
||||
#[
|
||||
#set enum(indent: 4.1em)
|
||||
1. การเชื่อมต่อเป็นแบบส่วนตัว (หรือมีความลับ) เนื่องจาก มีการใช้
|
||||
อัลกอริทึมคีย์แบบสมมาตรในการเข้ารหัสข้อมูลที่ส่ง
|
||||
คีย์สำหรับการเข้ารหัสแบบสมมาตรนี้จะถูกสร้างขึ้นอย่างเฉพาะเจาะจงสำหรับแต่ละการเชื่อมต่อ
|
||||
และอิงจากความลับร่วมที่เจรจากันไว้เมื่อเริ่มต้นเซสชัน
|
||||
เซิร์ฟเวอร์และไคลเอ็นต์จะเจรจารายละเอียดเกี่ยวกับอัลกอริทึมการเข้ารหัสและคีย์การเข้ารหัสที่จะใช้ก่อนที่จะส่งข้อมูลไบต์แรก
|
||||
(ดูด้านล่าง) การเจรจาความลับร่วมนั้นทั้งปลอดภัย
|
||||
(ความลับที่เจรจากันไว้จะไม่สามารถเข้าถึงได้โดยผู้ดักฟังและไม่สามารถได้รับ
|
||||
แม้แต่โดยผู้โจมตีที่วางตัวเองอยู่ตรงกลางการเชื่อมต่อ) และเชื่อถือได้
|
||||
(ไม่มีผู้โจมตีคนใดสามารถแก้ไขการสื่อสารระหว่างการเจรจาโดยไม่ถูกตรวจพบ)
|
||||
2. การยืนยันตัวตนของฝ่ายที่สื่อสารสามารถยืนยันได้โดยใช้การเข้ารหัสด้วยคีย์สาธารณะการยืนยันตัวตนนี้จำเป็นสำหรับเซิร์ฟเวอร์และเป็นทางเลือกสำหรับไคลเอนต์
|
||||
3. การเชื่อมต่อมีความน่าเชื่อถือ (หรือมีความสมบูรณ์)
|
||||
เนื่องจากข้อความแต่ละข้อความที่ส่งออกจะมีการตรวจสอบความสมบูรณ์ของข้อความโดยใช้รหัสยืนยันข้อความเพื่อป้องกันการสูญหายหรือการเปลี่ยนแปลงข้อมูลที่ไม่ถูกตรวจพบระหว่างการส่งข้อมูล
|
||||
]
|
||||
|
||||
#i มีการพยายามบ่อนทำลายแง่มุมด้านความปลอดภัยในการสื่อสารที่ TLS มุ่งหวังจะมอบให้ และโปรโตคอลนี้ได้รับการแก้ไขหลายครั้งเพื่อจัดการกับภัยคุกคามด้านความปลอดภัยเหล่านี้ นักพัฒนาเว็บเบราว์เซอร์ได้ปรับปรุงผลิตภัณฑ์ของตนซ้ำแล้วซ้ำเล่าเพื่อป้องกันจุดอ่อนด้านความปลอดภัยที่อาจเกิดขึ้นหลังจากค้นพบจุดอ่อนเหล่านี้ (ดูประวัติการสนับสนุน TLS/SSL ของเว็บเบราว์เซอร์)
|
||||
ความปลอดภัยของเลเยอร์การขนส่งดาต้าแกรม
|
||||
#iii TLS รองรับวิธีการที่หลากหลายสำหรับการแลกเปลี่ยนคีย์ การเข้ารหัสข้อมูล
|
||||
และการตรวจสอบความถูกต้องของข้อความ ดังนั้น การกำหนดค่า TLS
|
||||
อย่างปลอดภัยจึงเกี่ยวข้องกับพารามิเตอร์ที่กำหนดค่าได้มากมาย
|
||||
และตัวเลือกทั้งหมดไม่ได้มีคุณสมบัติที่เกี่ยวข้องกับความเป็นส่วนตัวทั้งหมดที่อธิบายไว้ในรายการด้านบน
|
||||
(ดูตารางด้านล่าง การแลกเปลี่ยนคีย์ ความปลอดภัยของการเข้ารหัสและความสมบูรณ์ของข้อมูล)
|
||||
|
||||
#i Datagram Transport Layer Security หรือเรียกย่อๆ ว่า DTLS เป็นโปรโตคอลการสื่อสาร ที่เกี่ยวข้องซึ่งให้ความปลอดภัยแก่ แอปพลิเคชันที่ใช้ Datagram โดยอนุญาตให้แอปพลิเคชันสื่อสารในลักษณะที่ออกแบบมาเพื่อป้องกันการดักฟัง การปลอมแปลงหรือการปลอมแปลงข้อความโปรโตคอล DTLS ใช้ โปรโตคอล Transport Layer Security (TLS) ที่เน้น การสตรีมและมีจุดประสงค์เพื่อให้การรับประกันความปลอดภัยที่คล้ายคลึงกัน อย่างไรก็ตาม โปรโตคอลนี้แตกต่างจาก TLS ตรงที่สามารถใช้งานร่วมกับโปรโตคอลที่เน้น Datagram ส่วนใหญ่ ได้แก่ User Datagram Protocol (UDP), Datagram Congestion Control Protocol (DCCP), Control And Provisioning of Wireless Access Points (CAPWAP), Stream Control Transmission Protocol (SCTP) encapsulation และ Secure Real-time Transport Protocol (SRTP)
|
||||
#iii มีการพยายามบ่อนทำลายแง่มุมด้านความปลอดภัยในการสื่อสารที่ TLS มุ่งหวังจะมอบให้
|
||||
และโปรโตคอลนี้ได้รับการแก้ไขหลายครั้งเพื่อจัดการกับภัยคุกคามด้านความปลอดภัยเหล่านี้
|
||||
นักพัฒนาเว็บเบราว์เซอร์ได้ปรับปรุงผลิตภัณฑ์ของตนซ้ำแล้วซ้ำเล่าเพื่อป้องกันจุดอ่อนด้านความปลอดภัยที่อาจเกิดขึ้นหลังจากค้นพบจุดอ่อนเหล่านี้
|
||||
(ดูประวัติการสนับสนุน TLS/SSL ของเว็บเบราว์เซอร์) ความปลอดภัยของเลเยอร์การขนส่งดาต้าแกรม
|
||||
|
||||
#i เนื่องจากเดตาแกรมของโปรโตคอล DTLS รักษาความหมายของการขนส่งพื้นฐานไว้ แอปพลิเคชันจึงไม่ประสบปัญหาความล่าช้าที่เกี่ยวข้องกับโปรโตคอลสตรีม อย่างไรก็ตาม แอปพลิเคชันต้องจัดการกับการเรียงลำดับแพ็กเก็ตใหม่ การสูญหายของเดตาแกรม และข้อมูลที่มีขนาดใหญ่กว่าขนาดของแพ็กเก็ตเครือข่าย เดตาแกรม เนื่องจาก DTLS ใช้ UDP หรือ SCTP แทน TCP จึงหลีกเลี่ยงปัญหา TCP ล่มเมื่อนำไปใช้สร้างอุโมงค์ VPN
|
||||
#iii Datagram Transport Layer Security หรือเรียกย่อๆ ว่า DTLS เป็นโปรโตคอลการสื่อสาร
|
||||
ที่เกี่ยวข้องซึ่งให้ความปลอดภัยแก่ แอปพลิเคชันที่ใช้ Datagram
|
||||
โดยอนุญาตให้แอปพลิเคชันสื่อสารในลักษณะที่ออกแบบมาเพื่อป้องกันการดักฟัง
|
||||
การปลอมแปลงหรือการปลอมแปลงข้อความโปรโตคอล DTLS ใช้ โปรโตคอล Transport Layer
|
||||
Security (TLS) ที่เน้น การสตรีมและมีจุดประสงค์เพื่อให้การรับประกันความปลอดภัยที่คล้ายคลึงกัน
|
||||
อย่างไรก็ตาม โปรโตคอลนี้แตกต่างจาก TLS ตรงที่สามารถใช้งานร่วมกับโปรโตคอลที่เน้น Datagram
|
||||
ส่วนใหญ่ ได้แก่ User Datagram Protocol (UDP), Datagram Congestion Control Protocol
|
||||
(DCCP), Control And Provisioning of Wireless Access Points (CAPWAP), Stream
|
||||
Control Transmission Protocol (SCTP) encapsulation และ Secure Real-time
|
||||
Transport Protocol (SRTP)
|
||||
|
||||
#i DTLS เวอร์ชัน 1.0 ฉบับดั้งเดิมในปี 2006 ไม่ใช่เอกสารแบบสแตนด์อโลน แต่ได้รับการกำหนดให้เป็นชุดเดลต้าของ TLS 1.1 ทำนองเดียวกัน DTLS เวอร์ชัน 2012 ที่ตามมาก็ถูกกำหนดให้เป็นเดลต้าของ TLS 1.2 โดยได้รับหมายเลขเวอร์ชันของ DTLS 1.2 เพื่อให้ตรงกับเวอร์ชัน TLS สุดท้าย DTLS 1.3 ปี 2022 ก็ถูกกำหนดให้เป็นเดลต้าของ TLS 1.3 เช่นเดียวกับสองเวอร์ชันก่อนหน้า DTLS 1.3 มีวัตถุประสงค์เพื่อให้ "การรับประกันความปลอดภัยที่เทียบเท่า [กับ TLS 1.3] ยกเว้นการป้องกันคำสั่ง/การไม่สามารถเล่นซ้ำได้"
|
||||
#iii เนื่องจากเดตาแกรมของโปรโตคอล DTLS รักษาความหมายของการขนส่งพื้นฐานไว้
|
||||
แอปพลิเคชันจึงไม่ประสบปัญหาความล่าช้าที่เกี่ยวข้องกับโปรโตคอลสตรีม อย่างไรก็ตาม
|
||||
แอปพลิเคชันต้องจัดการกับการเรียงลำดับแพ็กเก็ตใหม่ การสูญหายของเดตาแกรม
|
||||
และข้อมูลที่มีขนาดใหญ่กว่าขนาดของแพ็กเก็ตเครือข่าย เดตาแกรม เนื่องจาก DTLS ใช้ UDP หรือ SCTP
|
||||
แทน TCP จึงหลีกเลี่ยงปัญหา TCP ล่มเมื่อนำไปใช้สร้างอุโมงค์ VPN
|
||||
|
||||
#i ไคลเอนต์ VPN จำนวนมากรวมถึง Cisco AnyConnect & InterCloud Fabric, OpenConnect, อุโมงค์ ZScaler, F5 Networks Edge VPN Client และ Citrix Systems NetScaler ใช้ DTLS เพื่อรักษาความปลอดภัยการรับส่งข้อมูล UDP นอกจากนี้ เว็บเบราว์เซอร์สมัยใหม่ทั้งหมดยังรองรับ DTLS-SRTP สำหรับ WebRTC
|
||||
#iii DTLS เวอร์ชัน 1.0 ฉบับดั้งเดิมในปี 2006 ไม่ใช่เอกสารแบบสแตนด์อโลน
|
||||
แต่ได้รับการกำหนดให้เป็นชุดเดลต้าของ TLS 1.1 ทำนองเดียวกัน DTLS เวอร์ชัน 2012
|
||||
ที่ตามมาก็ถูกกำหนดให้เป็นเดลต้าของ TLS 1.2 โดยได้รับหมายเลขเวอร์ชันของ DTLS 1.2
|
||||
เพื่อให้ตรงกับเวอร์ชัน TLS สุดท้าย DTLS 1.3 ปี 2022 ก็ถูกกำหนดให้เป็นเดลต้าของ TLS 1.3
|
||||
เช่นเดียวกับสองเวอร์ชันก่อนหน้า DTLS 1.3 มีวัตถุประสงค์เพื่อให้ "การรับประกันความปลอดภัยที่เทียบเท่า
|
||||
[กับ TLS 1.3] ยกเว้นการป้องกันคำสั่ง/การไม่สามารถเล่นซ้ำได้"
|
||||
|
||||
#iii ไคลเอนต์ VPN จำนวนมากรวมถึง Cisco AnyConnect & InterCloud Fabric,
|
||||
OpenConnect, อุโมงค์ ZScaler, F5 Networks Edge VPN Client และ Citrix Systems
|
||||
NetScaler ใช้ DTLS เพื่อรักษาความปลอดภัยการรับส่งข้อมูล UDP นอกจากนี้
|
||||
เว็บเบราว์เซอร์สมัยใหม่ทั้งหมดยังรองรับ DTLS-SRTP สำหรับ WebRTC
|
||||
|
||||
#include "X509.typ"
|
||||
#include "x690.typ"
|
||||
|
||||
@@ -2,62 +2,119 @@
|
||||
|
||||
== X.509 (รูปแบบใบรับรอง TLS/SSL) <x509>
|
||||
|
||||
#i ในการเข้ารหัส X.509 เป็นมาตรฐานของสหภาพโทรคมนาคมระหว่างประเทศ (ITU) ที่กำหนดรูปแบบของใบรับรองคีย์สาธารณะใบรับรอง X.509 ถูกใช้ในโปรโตคอลอินเทอร์เน็ตมากมายรวมถึง TLS/SSL ซึ่งเป็นพื้นฐานของ HTTPS โปรโตคอลที่ปลอดภัยสำหรับการท่องเว็บ นอกจากนี้ยังใช้ในแอปพลิเคชันออฟไลน์เช่น ลาย เซ็นอิเล็กทรอนิกส์
|
||||
ใบรับรอง X.509 เชื่อมโยงข้อมูลประจำตัวกับคีย์สาธารณะโดยใช้ลายเซ็นดิจิทัล ใบรับรองประกอบด้วยข้อมูลประจำตัว (ชื่อโฮสต์องค์กร หรือบุคคล) และคีย์สาธารณะ (RSA, DSA, ECDSA, ed25519 เป็นต้น) ซึ่งลงนามโดยผู้ออกใบรับรองหรือลงนามด้วยตนเอง เมื่อใบรับรองได้รับการลงนามโดยผู้ออกใบรับรองที่เชื่อถือได้หรือผ่านการตรวจสอบความถูกต้องด้วยวิธีอื่น ผู้ถือใบรับรองนั้นสามารถใช้คีย์สาธารณะที่มีอยู่เพื่อสร้างการสื่อสารที่ปลอดภัยกับบุคคลอื่น หรือตรวจสอบความถูกต้องของเอกสารที่ลงนามดิจิทัลด้วย คีย์ส่วนตัวที่เกี่ยวข้องได้
|
||||
#iii ในการเข้ารหัส X.509 เป็นมาตรฐานของสหภาพโทรคมนาคมระหว่างประเทศ (ITU)
|
||||
ที่กำหนดรูปแบบของใบรับรองคีย์สาธารณะใบรับรอง X.509 ถูกใช้ในโปรโตคอลอินเทอร์เน็ตมากมายรวมถึง
|
||||
TLS/SSL ซึ่งเป็นพื้นฐานของ HTTPS โปรโตคอลที่ปลอดภัยสำหรับการท่องเว็บ
|
||||
นอกจากนี้ยังใช้ในแอปพลิเคชันออฟไลน์เช่น ลาย เซ็นอิเล็กทรอนิกส์ ใบรับรอง X.509
|
||||
เชื่อมโยงข้อมูลประจำตัวกับคีย์สาธารณะโดยใช้ลายเซ็นดิจิทัล ใบรับรองประกอบด้วยข้อมูลประจำตัว
|
||||
(ชื่อโฮสต์องค์กร หรือบุคคล) และคีย์สาธารณะ (RSA, DSA, ECDSA, ed25519 เป็นต้น)
|
||||
ซึ่งลงนามโดยผู้ออกใบรับรองหรือลงนามด้วยตนเอง
|
||||
เมื่อใบรับรองได้รับการลงนามโดยผู้ออกใบรับรองที่เชื่อถือได้หรือผ่านการตรวจสอบความถูกต้องด้วยวิธีอื่น
|
||||
ผู้ถือใบรับรองนั้นสามารถใช้คีย์สาธารณะที่มีอยู่เพื่อสร้างการสื่อสารที่ปลอดภัยกับบุคคลอื่น
|
||||
หรือตรวจสอบความถูกต้องของเอกสารที่ลงนามดิจิทัลด้วย คีย์ส่วนตัวที่เกี่ยวข้องได้
|
||||
|
||||
#i X.509 ยังกำหนดรายการเพิกถอนใบรับรองซึ่งเป็นวิธีการแจกจ่ายข้อมูลเกี่ยวกับใบรับรองที่ถือว่าไม่ถูกต้องโดยผู้มีอำนาจลงนาม ตลอดจนอัลกอริทึมการตรวจสอบเส้นทางการรับรองซึ่งช่วยให้ใบรับรองได้รับการลงนามโดยใบรับรอง CA ตัวกลาง ซึ่งใบรับรองเหล่านี้จะได้รับการลงนามโดยใบรับรองอื่นๆ ต่อไปจนไปถึงจุดยึดที่เชื่อถือได้ในที่สุด
|
||||
#iii X.509
|
||||
ยังกำหนดรายการเพิกถอนใบรับรองซึ่งเป็นวิธีการแจกจ่ายข้อมูลเกี่ยวกับใบรับรองที่ถือว่าไม่ถูกต้องโดยผู้มีอำนาจลงนาม
|
||||
ตลอดจนอัลกอริทึมการตรวจสอบเส้นทางการรับรองซึ่งช่วยให้ใบรับรองได้รับการลงนามโดยใบรับรอง CA
|
||||
ตัวกลาง ซึ่งใบรับรองเหล่านี้จะได้รับการลงนามโดยใบรับรองอื่น ๆ ต่อไปจนไปถึงจุดยึดที่เชื่อถือได้ในที่สุด
|
||||
|
||||
#i X.509 ถูกกำหนดโดย "Standardization Sector" ของ ITU (SG17 ของ ITU-T) ใน ITU-T Study Group 17 และมีพื้นฐานมาจาก Abstract Syntax Notation One (ASN.1) ซึ่งเป็นมาตรฐานอีกประการหนึ่งของ ITU-T
|
||||
#iii X.509 ถูกกำหนดโดย "Standardization Sector" ของ ITU (SG17 ของ ITU-T) ใน ITU-T
|
||||
Study Group 17 และมีพื้นฐานมาจาก Abstract Syntax Notation One (ASN.1)
|
||||
ซึ่งเป็นมาตรฐานอีกประการหนึ่งของ ITU-T
|
||||
|
||||
=== โครงสร้างของใบรับรอง
|
||||
#i โครงสร้างที่กำหนดไว้โดยมาตรฐานจะแสดงอยู่ในภาษาทางการที่เรียกว่า Abstract Syntax Notation One (ASN.1)
|
||||
#iiii โครงสร้างที่กำหนดไว้โดยมาตรฐานจะแสดงอยู่ในภาษาทางการที่เรียกว่า Abstract Syntax
|
||||
Notation One (ASN.1)
|
||||
|
||||
โครงสร้างของใบรับรองดิจิทัล X.509 v3 มีดังนี้:
|
||||
#iiii โครงสร้างของใบรับรองดิจิทัล X.509 v3 มีดังนี้
|
||||
|
||||
- ใบรับรอง
|
||||
- หมายเลขเวอร์ชัน
|
||||
- หมายเลขซีเรียล
|
||||
- รหัสอัลกอริทึมลายเซ็น
|
||||
- ชื่อผู้ออก
|
||||
- ระยะเวลาใช้งาน
|
||||
- ไม่ก่อน
|
||||
- ไม่หลังจากนั้น
|
||||
- ชื่อเรื่อง
|
||||
- ข้อมูลคีย์สาธารณะของเรื่อง
|
||||
- อัลกอริทึมคีย์สาธารณะ
|
||||
- คีย์สาธารณะของเรื่อง
|
||||
รหัสประจำตัวผู้ออก (ทางเลือก)
|
||||
รหัสประจำตัวเฉพาะเรื่อง (ทางเลือก)
|
||||
ส่วนขยาย (ทางเลือก)
|
||||
#[
|
||||
#set enum(indent: 7.55em)
|
||||
1. ใบรับรอง
|
||||
#listy(
|
||||
indent: 8.9em,
|
||||
numbering: thai-numbering,
|
||||
[หมายเลขเวอร์ชัน],
|
||||
[หมายเลขซีเรียล],
|
||||
[รหัสอัลกอริทึมลายเซ็น],
|
||||
[ชื่อผู้ออก],
|
||||
[ระยะเวลาใช้งาน โดยระบุเวลาไม่ก่อนและไม่หลังจากนั้น],
|
||||
[ชื่อเรื่อง],
|
||||
[ข้อมูลคีย์สาธารณะของเรื่อง ได้แก่ อัลกอริทึมคีย์สาธารณะ
|
||||
คีย์สาธารณะของเรื่องเช่นรหัสประจำตัวผู้ออก (ไม่จำเป็น) รหัสประจำตัวเฉพาะเรื่อง (ไม่จำเป็น)
|
||||
ส่วนขยาย (ไม่จำเป็น)],
|
||||
)
|
||||
2. อัลกอริทึมลายเซ็นใบรับรอง
|
||||
3. ลายเซ็นใบรับรอง
|
||||
]
|
||||
|
||||
- อัลกอริทึมลายเซ็นใบรับรอง
|
||||
- ลายเซ็นใบรับรอง
|
||||
#iiii ฟิลด์ส่วนขยาย (ถ้ามี) จะเป็นลำดับของส่วนขยายใบรับรองอย่างน้อยหนึ่งรายการ
|
||||
แต่ละส่วนขยายมีรหัสประจำตัวเฉพาะของตัวเอง ซึ่งแสดงเป็นตัวระบุวัตถุ (OID)
|
||||
ซึ่งเป็นชุดค่าพร้อมกับข้อบ่งชี้ที่สำคัญหรือไม่สำคัญ
|
||||
ระบบที่ใช้ใบรับรองต้องปฏิเสธใบรับรองหากพบส่วนขยายที่สำคัญที่ไม่รู้จักหรือส่วนขยายที่สำคัญซึ่งมีข้อมูลที่ไม่สามารถประมวลผลได้
|
||||
ส่วนขยายที่ไม่สำคัญอาจถูกละเว้นหากไม่รู้จัก แต่จะต้องได้รับการประมวลผลหากรู้จักส่วนขยายใบรับรอง
|
||||
|
||||
#i ฟิลด์ส่วนขยาย (ถ้ามี) จะเป็นลำดับของส่วนขยายใบรับรองอย่างน้อยหนึ่งรายการ แต่ละส่วนขยายมีรหัสประจำตัวเฉพาะของตัวเอง ซึ่งแสดงเป็นตัวระบุวัตถุ (OID) ซึ่งเป็นชุดค่าพร้อมกับข้อบ่งชี้ที่สำคัญหรือไม่สำคัญ ระบบที่ใช้ใบรับรองต้องปฏิเสธใบรับรองหากพบส่วนขยายที่สำคัญที่ไม่รู้จักหรือส่วนขยายที่สำคัญซึ่งมีข้อมูลที่ไม่สามารถประมวลผลได้ ส่วนขยายที่ไม่สำคัญอาจถูกละเว้นหากไม่รู้จัก แต่จะต้องได้รับการประมวลผลหากรู้จักส่วนขยายใบรับรอง
|
||||
#iiii โครงสร้างของเวอร์ชัน 1 มีอยู่ ใน RFC 1422
|
||||
|
||||
#i โครงสร้างของเวอร์ชัน 1 มีอยู่ ใน RFC 1422
|
||||
#iiii รูปแบบภายในของตัวระบุเฉพาะของผู้เผยแพร่และเรื่องที่ระบุไว้ใน X.520 ไดเร็กทอรี:คำแนะนำ
|
||||
ประเภทแอตทริบิวต์ที่เลือก
|
||||
|
||||
#i รูปแบบภายในของตัวระบุเฉพาะของผู้เผยแพร่และเรื่องที่ระบุไว้ใน X.520 ไดเร็กทอรี:คำแนะนำ ประเภทแอตทริบิวต์ที่เลือก
|
||||
#iiii ITU-T ได้นำตัวระบุเฉพาะของผู้ออกหลักทรัพย์และบุคคลมาใช้ในเวอร์ชัน 2
|
||||
เพื่ออนุญาตให้นำชื่อผู้ออกหลักทรัพย์หรือบุคคลมาใช้ซ้ำได้หลังจากระยะเวลาหนึ่ง
|
||||
ตัวอย่างหนึ่งของการนำกลับมาใช้ซ้ำคือเมื่อ CA ล้มละลายและชื่อถูกลบออกจากรายชื่อสาธารณะของประเทศ
|
||||
หลังจากนั้น CA อื่นที่มีชื่อเดียวกันอาจลงทะเบียนตัวเองได้ แม้ว่าจะไม่เกี่ยวข้องกับ CA แรกก็ตาม
|
||||
อย่างไรก็ตาม IETF แนะนำว่าไม่ควรนำชื่อผู้ออกหลักทรัพย์และบุคคลมาใช้ซ้ำ ดังนั้นเวอร์ชัน 2
|
||||
จึงยังไม่แพร่หลายในอินเทอร์เน็ต
|
||||
|
||||
#i ITU-T ได้นำตัวระบุเฉพาะของผู้ออกหลักทรัพย์และบุคคลมาใช้ในเวอร์ชัน 2 เพื่ออนุญาตให้นำชื่อผู้ออกหลักทรัพย์หรือบุคคลมาใช้ซ้ำได้หลังจากระยะเวลาหนึ่ง ตัวอย่างหนึ่งของการนำกลับมาใช้ซ้ำคือเมื่อ CA ล้มละลายและชื่อถูกลบออกจากรายชื่อสาธารณะของประเทศ หลังจากนั้น CA อื่นที่มีชื่อเดียวกันอาจลงทะเบียนตัวเองได้ แม้ว่าจะไม่เกี่ยวข้องกับ CA แรกก็ตาม อย่างไรก็ตาม IETF แนะนำว่าไม่ควรนำชื่อผู้ออกหลักทรัพย์และบุคคลมาใช้ซ้ำ ดังนั้นเวอร์ชัน 2 จึงยังไม่แพร่หลายในอินเทอร์เน็ต
|
||||
#iiii ส่วนขยายได้รับการแนะนำในเวอร์ชัน 3 CA
|
||||
สามารถใช้ส่วนขยายเพื่อออกใบรับรองได้เฉพาะสำหรับจุดประสงค์เฉพาะ (เช่น
|
||||
สำหรับการลงนามในวัตถุดิจิทัล เท่านั้น)
|
||||
|
||||
#i ส่วนขยายได้รับการแนะนำในเวอร์ชัน 3 CA สามารถใช้ส่วนขยายเพื่อออกใบรับรองได้เฉพาะสำหรับจุดประสงค์เฉพาะ (เช่น สำหรับการลงนามในวัตถุดิจิทัล เท่านั้น)
|
||||
|
||||
#i ในทุกเวอร์ชันหมายเลขซีเรียลจะต้องไม่ซ้ำกันสำหรับใบรับรองแต่ละใบที่ออกโดย CA เฉพาะ (ดังที่กล่าวถึงใน RFC 5280)
|
||||
#iiii ในทุกเวอร์ชันหมายเลขซีเรียลจะต้องไม่ซ้ำกันสำหรับใบรับรองแต่ละใบที่ออกโดย CA เฉพาะ
|
||||
(ดังที่กล่าวถึงใน RFC 5280)
|
||||
|
||||
=== นามสกุลไฟล์ใบรับรอง
|
||||
#i นามสกุลไฟล์ที่ใช้กันทั่วไปสำหรับใบรับรอง X.509 มีหลายประเภทนามสกุลไฟล์เหล่านี้ยังใช้สำหรับข้อมูลอื่นๆ เช่น คีย์ส่วนตัวด้วย
|
||||
#iiii นามสกุลไฟล์ที่ใช้กันทั่วไปสำหรับใบรับรอง X.509
|
||||
มีหลายประเภทนามสกุลไฟล์เหล่านี้ยังใช้สำหรับข้อมูลอื่น ๆ เช่น คีย์ส่วนตัวด้วย
|
||||
|
||||
- `.pem` -- (อีเมลอิเล็กทรอนิกส์ที่เพิ่มความเป็นส่วนตัว) ใบรับรอง DER ที่เข้ารหัส Base64 แนบระหว่าง `-----BEGIN CERTIFICATE-----` และ `-----END CERTIFICATE-----`
|
||||
- `.cer`, `.crt`, `.der` -- โดยปกติจะอยู่ในรูปแบบไบนารี DER แต่ใบรับรองที่เข้ารหัส Base64 ก็เป็นเรื่องปกติเช่นกัน (ดู `.pem` ด้านบน)
|
||||
- `.p8`, `.p8e`, `.pk8` -- คีย์ส่วนตัวที่ส่งออกตามที่ระบุไว้ใน PKCS\#8 อาจอยู่ในรูปแบบ DER หรือ PEM ที่ขึ้นต้นด้วย `-----BEGIN PRIVATE KEY-----` คีย์ที่เข้ารหัสจะขึ้นต้นด้วย `-----BEGIN ENCRYPTED PRIVATE KEY-----` และอาจมี `.p8e` เป็นนามสกุลไฟล์
|
||||
- `.p10`, `.csr` -- PKCS\#10 เป็นคำขอลงนามใบรับรอง (CSR) ในรูปแบบ PEM ขึ้นต้นด้วย `-----BEGIN CERTIFICATE REQUEST-----` แบบฟอร์มเหล่านี้สร้างขึ้นเพื่อส่งไปยังผู้ออกใบรับรอง (CA) แบบฟอร์มประกอบด้วยรายละเอียดสำคัญของใบรับรองที่ร้องขอ เช่น ชื่อสามัญ (/CN), หัวเรื่อง, องค์กร, รัฐ, ประเทศ รวมถึงคีย์สาธารณะของใบรับรองที่ต้องการให้ลงนาม คีย์เหล่านี้จะได้รับการลงนามโดย CA และใบรับรองจะถูกส่งกลับคืน ใบรับรองที่ส่งคืนคือใบรับรอง สาธารณะ (ซึ่งมีคีย์สาธารณะแต่ไม่มีคีย์ส่วนตัว) ซึ่งตัวใบรับรองเองสามารถอยู่ในรูปแบบต่างๆ ได้หลายรูปแบบ แต่โดยปกติจะเป็น `.p7r`
|
||||
- `.p7r` -- คำตอบ ของ PKCS\#7 ต่อ CSR ประกอบด้วยใบรับรองที่เพิ่งลงนาม และใบรับรองของ CA เอง
|
||||
- `.p7s` -- ลายเซ็นดิจิทัล PKCS\#7 อาจมีไฟล์หรือข้อความที่ลงนามต้นฉบับ ใช้ใน S/MIME สำหรับการลงนามในอีเมลกำหนดไว้ใน RFC 2311
|
||||
- `.p7m` -- PKCS\#7 (SignedData, EnvelopedData) ข้อความ เช่น ไฟล์ที่เข้ารหัส ("enveloped") ข้อความ หรือจดหมายอีเมล MIME กำหนดไว้ใน RFC 2311
|
||||
- `.p7c` -- โครงสร้าง SignedData แบบ "certs-only" ของ PKCS\#7 ที่เสื่อมลง โดยไม่มีข้อมูลใดๆ ให้ลงนาม กำหนดไว้ใน RFC 2311
|
||||
- `.p7b` -- โครงสร้าง SignedData ของ PKCS\#7 ที่ไม่มีข้อมูล มีเพียงใบรับรองแบบบันเดิลหรือ CRL (ไม่ค่อยเกิดขึ้น) แต่ไม่มีคีย์ส่วนตัว ใช้รูปแบบ DER หรือ BER หรือ PEM ที่ขึ้นต้นด้วย `-----BEGIN PKCS7-----` รูปแบบที่ Windows ใช้สำหรับการแลกเปลี่ยนใบรับรอง รองรับโดย Java แต่มักใช้นามสกุล `.keystore` แทน ซึ่งแตกต่างจากใบรับรองแบบ `.pem` รูปแบบนี้มีวิธีที่กำหนดไว้สำหรับการรวมใบรับรองเส้นทางการรับรอง
|
||||
- `.p12`, `.pfx`, `.pkcs12` -- PKCS\#12 อาจมีใบรับรอง (สาธารณะ) และคีย์ส่วนตัว (ป้องกันด้วยรหัสผ่าน) ในไฟล์เดียว `.pfx` - _Personal Information eXchange_ PFX ซึ่งเป็นรุ่นก่อนของ PKCS\#12 (โดยปกติจะมีข้อมูลในรูปแบบ PKCS\#12 เช่น ไฟล์ PFX ที่สร้างใน IIS)
|
||||
- `.crl` -- รายการเพิกถอนใบรับรอง (CRL) หน่วยงานที่ออกใบรับรองจะจัดทำรายการเหล่านี้ขึ้นเพื่อใช้ในการเพิกถอนใบรับรองก่อนหมดอายุ
|
||||
#[
|
||||
#set enum(indent: 7.55em)
|
||||
1. `.pem` -- (อีเมลอิเล็กทรอนิกส์ที่เพิ่มความเป็นส่วนตัว) ใบรับรอง DER ที่เข้ารหัส Base64
|
||||
แนบระหว่าง `-----BEGIN CERTIFICATE-----` และ `-----END CERTIFICATE-----`
|
||||
2. `.cer`, `.crt`, `.der` -- โดยปกติจะอยู่ในรูปแบบไบนารี DER แต่ใบรับรองที่เข้ารหัส
|
||||
Base64 ก็เป็นเรื่องปกติเช่นกัน (ดู `.pem` ด้านบน)
|
||||
3. `.p8`, `.p8e`, `.pk8` -- คีย์ส่วนตัวที่ส่งออกตามที่ระบุไว้ใน PKCS\#8 อาจอยู่ในรูปแบบ DER
|
||||
หรือ PEM ที่ขึ้นต้นด้วย `-----BEGIN PRIVATE KEY-----` คีย์ที่เข้ารหัสจะขึ้นต้นด้วย
|
||||
`-----BEGIN ENCRYPTED PRIVATE KEY-----` และอาจมี `.p8e` เป็นนามสกุลไฟล์
|
||||
4. `.p10`, `.csr` -- PKCS\#10 เป็นคำขอลงนามใบรับรอง (CSR) ในรูปแบบ PEM ขึ้นต้นด้วย
|
||||
`-----BEGIN CERTIFICATE REQUEST-----` แบบฟอร์มเหล่านี้สร้างขึ้นเพื่อส่งไปยังผู้ออกใบรับรอง
|
||||
(CA) แบบฟอร์มประกอบด้วยรายละเอียดสำคัญของใบรับรองที่ร้องขอ เช่น ชื่อสามัญ (/CN), หัวเรื่อง,
|
||||
องค์กร, รัฐ, ประเทศ รวมถึงคีย์สาธารณะของใบรับรองที่ต้องการให้ลงนาม
|
||||
คีย์เหล่านี้จะได้รับการลงนามโดย CA และใบรับรองจะถูกส่งกลับคืน ใบรับรองที่ส่งคืนคือใบรับรอง
|
||||
สาธารณะ (ซึ่งมีคีย์สาธารณะแต่ไม่มีคีย์ส่วนตัว) ซึ่งตัวใบรับรองเองสามารถอยู่ในรูปแบบต่างๆ
|
||||
ได้หลายรูปแบบ แต่โดยปกติจะเป็น `.p7r`
|
||||
5. `.p7r` -- คำตอบ ของ PKCS\#7 ต่อ CSR ประกอบด้วยใบรับรองที่เพิ่งลงนาม และใบรับรองของ
|
||||
CA เอง
|
||||
6. `.p7s` -- ลายเซ็นดิจิทัล PKCS\#7 อาจมีไฟล์หรือข้อความที่ลงนามต้นฉบับ ใช้ใน S/MIME
|
||||
สำหรับการลงนามในอีเมลกำหนดไว้ใน RFC 2311
|
||||
7. `.p7m` -- PKCS\#7 (SignedData, EnvelopedData) ข้อความ เช่น ไฟล์ที่เข้ารหัส
|
||||
("enveloped") ข้อความ หรือจดหมายอีเมล MIME กำหนดไว้ใน RFC 2311
|
||||
8. `.p7c` -- โครงสร้าง SignedData แบบ "certs-only" ของ PKCS\#7 ที่เสื่อมลง
|
||||
โดยไม่มีข้อมูลใดๆ ให้ลงนาม กำหนดไว้ใน RFC 2311
|
||||
9. `.p7b` -- โครงสร้าง SignedData ของ PKCS\#7 ที่ไม่มีข้อมูล มีเพียงใบรับรองแบบบันเดิลหรือ
|
||||
CRL (ไม่ค่อยเกิดขึ้น) แต่ไม่มีคีย์ส่วนตัว ใช้รูปแบบ DER หรือ BER หรือ PEM ที่ขึ้นต้นด้วย
|
||||
`-----BEGIN PKCS7-----` รูปแบบที่ Windows ใช้สำหรับการแลกเปลี่ยนใบรับรอง รองรับโดย
|
||||
Java แต่มักใช้นามสกุล `.keystore` แทน ซึ่งแตกต่างจากใบรับรองแบบ `.pem`
|
||||
รูปแบบนี้มีวิธีที่กำหนดไว้สำหรับการรวมใบรับรองเส้นทางการรับรอง
|
||||
10. `.p12`, `.pfx`, `.pkcs12` -- PKCS\#12 อาจมีใบรับรอง (สาธารณะ) และคีย์ส่วนตัว
|
||||
(ป้องกันด้วยรหัสผ่าน) ในไฟล์เดียว `.pfx` - _Personal Information eXchange_ PFX
|
||||
ซึ่งเป็นรุ่นก่อนของ PKCS\#12 (โดยปกติจะมีข้อมูลในรูปแบบ PKCS\#12 เช่น ไฟล์ PFX ที่สร้างใน
|
||||
IIS)
|
||||
11. `.crl` -- รายการเพิกถอนใบรับรอง (CRL)
|
||||
หน่วยงานที่ออกใบรับรองจะจัดทำรายการเหล่านี้ขึ้นเพื่อใช้ในการเพิกถอนใบรับรองก่อนหมดอายุ
|
||||
]
|
||||
|
||||
#i PKCS\#7 เป็นมาตรฐานสำหรับการลงนามหรือเข้ารหัสข้อมูล (เรียกอย่างเป็นทางการว่า "enveloping") เนื่องจากจำเป็นต้องใช้ใบรับรองเพื่อตรวจสอบข้อมูลที่ลงนามแล้วจึงสามารถรวมใบรับรองไว้ในโครงสร้าง SignedData ได้
|
||||
#iiii PKCS\#7 เป็นมาตรฐานสำหรับการลงนามหรือเข้ารหัสข้อมูล (เรียกอย่างเป็นทางการว่า
|
||||
"enveloping")
|
||||
เนื่องจากจำเป็นต้องใช้ใบรับรองเพื่อตรวจสอบข้อมูลที่ลงนามแล้วจึงสามารถรวมใบรับรองไว้ในโครงสร้าง
|
||||
SignedData ได้
|
||||
|
||||
@@ -1,25 +1,26 @@
|
||||
#import "../PageTemplate.typ": i
|
||||
#import "../PageTemplate.typ": *
|
||||
#set heading(numbering: "1.1", offset: 2)
|
||||
|
||||
= X.690 (การเข้ารหัส DER)
|
||||
|
||||
X.690 เป็น มาตรฐาน ITU-T ที่ระบุรูปแบบการเข้ารหัส ASN.1 หลายรูปแบบ:
|
||||
#iii X.690 เป็น มาตรฐาน ITU-T ที่ระบุรูปแบบการเข้ารหัส ASN.1 หลายรูปแบบ
|
||||
|
||||
- กฎการเข้ารหัสพื้นฐาน (BER)
|
||||
- กฎการเข้ารหัสแบบ Canonical (CER)
|
||||
- กฎการเข้ารหัสที่โดดเด่น (DER)
|
||||
== กฎการเข้ารหัสพื้นฐาน (BER)
|
||||
|
||||
กฎการเข้ารหัสพื้นฐาน (BER) คือกฎดั้งเดิมที่วางไว้โดยมาตรฐาน ASN.1 สำหรับการเข้ารหัสข้อมูลในรูปแบบไบนารี กฎเหล่านี้ ซึ่งเรียกรวมกันว่าไวยากรณ์การถ่ายโอนในภาษา ASN.1 กำหนดจำนวนอ็อกเท็ต (ไบต์ 8 บิต) ที่ใช้ในการเข้ารหัสข้อมูล
|
||||
#iiii กฎการเข้ารหัสพื้นฐาน (BER) คือกฎดั้งเดิมที่วางไว้โดยมาตรฐาน ASN.1
|
||||
สำหรับการเข้ารหัสข้อมูลในรูปแบบไบนารี กฎเหล่านี้ ซึ่งเรียกรวมกันว่าไวยากรณ์การถ่ายโอนในภาษา ASN.1
|
||||
กำหนดจำนวนอ็อกเท็ต (ไบต์ 8 บิต) ที่ใช้ในการเข้ารหัสข้อมูล
|
||||
|
||||
#i โดยโครงงานนี้ใช้ใบรับรองในรูปแบบการเข้ารหัส DER ซึ่ง DER (Distinguished Encoding Rules) เป็น BER แบบจำกัดรูปแบบหนึ่งสำหรับการสร้างไวยากรณ์การถ่ายโอนข้อมูลที่ชัดเจนสำหรับโครงสร้างข้อมูลที่อธิบายโดย ASN.1 เช่นเดียวกับ CER การเข้ารหัส DER ถือเป็นการเข้ารหัส BER ที่ถูกต้อง DER เหมือนกับ BER โดยตัดตัวเลือกของผู้ส่งออกทั้งหมด ยกเว้นตัวเลือกเดียว
|
||||
== กฎการเข้ารหัสที่โดดเด่น (DER)
|
||||
|
||||
DER เป็นส่วนย่อยของ BER ที่ให้วิธีการเข้ารหัสค่า ASN.1 เพียงวิธีเดียว DER มีไว้สำหรับสถานการณ์ที่จำเป็นต้องมีการเข้ารหัสเฉพาะ เช่น ในการเข้ารหัสลับและช่วยให้มั่นใจว่าโครงสร้างข้อมูลที่จำเป็นต้องมีการลงนามดิจิทัลจะสร้างการแสดงแบบอนุกรมที่ไม่ซ้ำกัน DER ถือเป็นรูปแบบมาตรฐานของ BER ตัวอย่างเช่นใน BER ค่าบูลีน true สามารถเข้ารหัสเป็นค่าไบต์ที่ไม่ใช่ศูนย์ 255 ค่า ในขณะที่ DER มีวิธีการเข้ารหัสค่าบูลีน true เพียงวิธีเดียว
|
||||
#iiii โดยโครงงานนี้ใช้ใบรับรองในรูปแบบการเข้ารหัส DER ซึ่ง DER (Distinguished Encoding
|
||||
Rules) เป็น BER
|
||||
แบบจำกัดรูปแบบหนึ่งสำหรับการสร้างไวยากรณ์การถ่ายโอนข้อมูลที่ชัดเจนสำหรับโครงสร้างข้อมูลที่อธิบายโดย
|
||||
ASN.1 เช่นเดียวกับ CER การเข้ารหัส DER ถือเป็นการเข้ารหัส BER ที่ถูกต้อง DER เหมือนกับ BER
|
||||
โดยตัดตัวเลือกของผู้ส่งออกทั้งหมด ยกเว้นตัวเลือกเดียว
|
||||
|
||||
ข้อจำกัดการเข้ารหัส DER ที่สำคัญที่สุดคือ:
|
||||
|
||||
1. การเข้ารหัสความยาวจะต้องใช้รูปแบบที่แน่นอน
|
||||
- นอกจากนี้ จะต้องใช้การเข้ารหัสที่มีความยาวสั้นที่สุดเท่าที่จะเป็นไปได้
|
||||
2. บิตสตริง อ็อกเท็ตสตริง และสตริงอักขระที่จำกัดต้องใช้การเข้ารหัสแบบดั้งเดิม
|
||||
3. องค์ประกอบของชุดจะถูกเข้ารหัสตามลำดับการเรียงลำดับตามค่าแท็ก
|
||||
|
||||
DER ถูกใช้กันอย่างแพร่หลายสำหรับใบรับรอง ดิจิทัลเช่น X.509
|
||||
#iiii DER เป็นส่วนย่อยของ BER ที่ให้วิธีการเข้ารหัสค่า ASN.1 เพียงวิธีเดียว DER
|
||||
มีไว้สำหรับสถานการณ์ที่จำเป็นต้องมีการเข้ารหัสเฉพาะ เช่น
|
||||
ในการเข้ารหัสลับและช่วยให้มั่นใจว่าโครงสร้างข้อมูลที่จำเป็นต้องมีการลงนามดิจิทัลจะสร้างการแสดงแบบอนุกรมที่ไม่ซ้ำกัน
|
||||
DER ถือเป็นรูปแบบมาตรฐานของ BER ตัวอย่างเช่นใน BER ค่าบูลีน true
|
||||
สามารถเข้ารหัสเป็นค่าไบต์ที่ไม่ใช่ศูนย์ 255 ค่า ในขณะที่ DER มีวิธีการเข้ารหัสค่าบูลีน true เพียงวิธีเดียว
|
||||
|
||||
@@ -1,410 +0,0 @@
|
||||
#import "PageTemplate.typ": *
|
||||
#import "@preview/fletcher:0.5.8" as fletcher: diagram, edge, node
|
||||
#import fletcher.shapes: circle, diamond, pill
|
||||
#show: chapter-page
|
||||
#set heading(numbering: "บทที่ 1")
|
||||
|
||||
#heading([#linebreak()วิธีการดำเนินโครงงาน])
|
||||
#set heading(numbering: "1.1")
|
||||
|
||||
#i ในการดำเนินการศึกษาครั้งนี้
|
||||
คณะผู้จัดทำโครงงานได้ศึกษาข้อมูลเบื้องต้นในการสร้างเครื่องยืนยันตัวตนด้วย NFC
|
||||
และได้ดำเนินการตามขั้นตอนนี้
|
||||
|
||||
+ วางแผนการดำเนินงาน
|
||||
+ การออกแบบ
|
||||
+ วัสดุอุปกรณ์
|
||||
+ ขั้นตอนการประกอบ
|
||||
+ การทดลอง
|
||||
+ การวิเคราะห์ข้อมูล
|
||||
|
||||
== วางแผนการดำเนินงาน
|
||||
|
||||
#show table.cell.where(y: 1): strong
|
||||
#set par(leading: 0.5em)
|
||||
|
||||
#let arrow = [
|
||||
#place(
|
||||
left + horizon,
|
||||
text(weight: "bold", size: 14pt)[#sym.arrow.l],
|
||||
dx: -5pt,
|
||||
dy: -0.7pt,
|
||||
)
|
||||
#place(
|
||||
horizon,
|
||||
line(length: 100%, stroke: (thickness: 1pt)),
|
||||
dx: 0pt,
|
||||
dy: 0pt,
|
||||
)
|
||||
#place(
|
||||
right + horizon,
|
||||
text(weight: "bold", size: 14pt)[#sym.arrow.r],
|
||||
dx: 5pt,
|
||||
dy: -0.7pt,
|
||||
)
|
||||
]
|
||||
|
||||
=== แผนขั้นตอนและวิธีการดำเนินงาน
|
||||
|
||||
#table(
|
||||
columns: 12,
|
||||
align: (
|
||||
left + horizon,
|
||||
center,
|
||||
center,
|
||||
center,
|
||||
center,
|
||||
center,
|
||||
center,
|
||||
center,
|
||||
center,
|
||||
center,
|
||||
center,
|
||||
center,
|
||||
),
|
||||
table.header(
|
||||
table.cell(
|
||||
[ขั้นตอนการ\ ดำเนินการ],
|
||||
rowspan: 2,
|
||||
),
|
||||
table.cell(
|
||||
[พ.ศ.2568],
|
||||
colspan: 3,
|
||||
),
|
||||
table.cell(
|
||||
[พ.ศ.2569],
|
||||
colspan: 8,
|
||||
),
|
||||
[ต.ค.],
|
||||
[พ.ย.],
|
||||
[ธ.ค.],
|
||||
[ม.ค.],
|
||||
[ก.พ.],
|
||||
[มี.ค],
|
||||
[เม.ย],
|
||||
[พ.ค.],
|
||||
[มิ.ย.],
|
||||
[ก.ค.],
|
||||
[ส.ค.],
|
||||
),
|
||||
[ศึกษาค้นคว้าข้อมูล],
|
||||
table.cell(arrow, colspan: 3),
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[เสนอหัวข้อ], arrow, [], [], [], [], [], [], [], [], [], [],
|
||||
[เสนอครั้งที่ 1], [], arrow, [], [], [], [], [], [], [], [], [],
|
||||
[ออกแบบและสร้าง], [], table.cell(arrow, colspan: 5), [], [], [], [], [],
|
||||
[จัดซื้ออุปกรณ์ทดลอง],
|
||||
[],
|
||||
table.cell(arrow, colspan: 3),
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[],
|
||||
[ทดลองการทำงาน], [], [], table.cell(arrow, colspan: 4), [], [], [], [], [],
|
||||
[ปรับปรุงแก้ไข], [], [], [], [], table.cell(arrow, colspan: 5), [], [],
|
||||
[เสนอครั้งที่ 2], [], [], [], arrow, [], [], [], [], [], [], [],
|
||||
[จัดทำรูปเล่ม], table.cell(arrow, colspan: 11),
|
||||
[นำเสนอโครงงาน], [], [], [], [], [], [], [], [], [], [], [],
|
||||
)
|
||||
|
||||
=== ผังการดำเนินงาน
|
||||
|
||||
#diagram(
|
||||
node-stroke: 1pt,
|
||||
spacing: 2em,
|
||||
node((0, 0), [เริ่มต้น], shape: pill),
|
||||
edge("-|>"),
|
||||
node((0, 1), shape: circle, radius: 1em),
|
||||
edge("-|>"),
|
||||
node((0, 2), [ศึกษาข้อมูลและทฤษฏีที่เกี่ยวข้อง], width: 2.5in),
|
||||
edge("-|>"),
|
||||
node((0, 3), [ออกแบบและวางแผนการดําเนินงาน], width: 2.5in),
|
||||
edge("-|>"),
|
||||
node((0, 4), [เครื่องยืนยันตัวตนด้วย NFC], width: 2.5in),
|
||||
edge("-|>"),
|
||||
node((0, 5), [ทดสอบประสิทธิภาพ], shape: diamond),
|
||||
edge("r,u,u,u,u,l", "-|>", [ไม่ผ่าน]),
|
||||
edge("-|>", [ผ่าน]),
|
||||
node((0, 6), [จัดทำเอกสาร], width: 2.5in),
|
||||
edge("-|>"),
|
||||
node((0, 7), [นำเสนอ], width: 2.5in),
|
||||
edge("-|>"),
|
||||
node((0, 8), [สิ้นสุด], shape: pill),
|
||||
)
|
||||
|
||||
#pagebreak()
|
||||
|
||||
=== ผังการทำงาน
|
||||
|
||||
#diagram(
|
||||
node-stroke: 1pt,
|
||||
spacing: 2em,
|
||||
node([เริ่มต้น], shape: pill),
|
||||
edge("-|>"),
|
||||
node((1, 0), [ตั้งค่า LittleFS]),
|
||||
edge("-|>"),
|
||||
|
||||
node((1, 2), [มี Wi-Fi บันทึก\ ไว้อยู่หรือไม่], shape: diamond),
|
||||
edge("l", "-|>", [ไม่มี]),
|
||||
edge((1, 2), (1, 3), "-|>", [มี]),
|
||||
|
||||
node((0, 2), [รอรับรายละเอียดเครือข่าย\ (ESP-Touch)]),
|
||||
edge("d,r", "-|>"),
|
||||
node((1, 3), [เชื่อมต่อเครือข่าย]),
|
||||
edge("-|>"),
|
||||
|
||||
node((0, 4), [มีอุปกรณ์ควบคุม\ หลักแล้วหรือไม่], shape: diamond),
|
||||
edge("-|>", [ไม่มี]),
|
||||
edge("d", "-|>", [มี]),
|
||||
|
||||
node((1, 4), [สร้างโทเค็นสำหรับการยืนยัน\ อุปกรณ์ควบคุมหลัก]),
|
||||
edge("-|>"),
|
||||
|
||||
node((1, 5), [รออุปกรณ์ควบคุมหลัก\ แตะเซนเซอร์ NFC]),
|
||||
edge("-|>"),
|
||||
|
||||
node((0, 5), [ตั้งค่าเซิร์ฟเวอร์ HTTPS]),
|
||||
edge("-|>"),
|
||||
|
||||
node((0, 6), shape: circle, radius: 1em),
|
||||
edge("-|>"),
|
||||
|
||||
node((0, 7), [มีการแตะเซนเซอร์\ NFC ขาเข้าหรือไม่], shape: diamond),
|
||||
edge("-|>", [ไม่มี]),
|
||||
|
||||
node((0, 9), [มีคนผ่านเซนเซอร์ PIR\ โดยไม่ได้รับอนุญาตหรือไม่], shape: diamond),
|
||||
edge((0, 9), (0, 10), [ไม่มี]),
|
||||
edge((0, 7), (1, 6), "-|>", [มี]),
|
||||
|
||||
node((1, 6), [อยู่ในโหมดลงทะเบียน\ หรือไม่], shape: diamond),
|
||||
edge("-|>", [ใช่]),
|
||||
edge((1, 6), (2, 7), [ไม่]),
|
||||
|
||||
node((1, 7), [นำ ID อุปกรณ์เข้า\ สู่รายการทะเบียน]),
|
||||
edge((1, 7), (0.6, 7), (0, 9), "-|>"),
|
||||
|
||||
node((2, 7), [ID ของอุปกรณ์อยู่\ ในทะเบียนหรือไม่], shape: diamond),
|
||||
edge("-|>", [อยู่]),
|
||||
edge((2, 7), (1, 8), "-|>", [ไม่อยู่], label-sep: -5pt),
|
||||
|
||||
node((2, 8), [ส่งเสียงคอนเฟิร์ม]),
|
||||
edge((2, 8), (2, 8.5), (0.4, 8.5), (0, 9), "-|>"),
|
||||
|
||||
node((1, 8), [ส่งเสียงแสดงความผิดพลาด]),
|
||||
edge((1, 8), (0.5, 8), (0, 9), "-|>"),
|
||||
|
||||
node((1, 9), [แจ้งเตือนทางเสียง\ และแอพลิเคชัน]),
|
||||
edge((1, 9), (0, 10), "-|>"),
|
||||
edge((0, 10), (1, 10), "-|>", [มี]),
|
||||
|
||||
node((0, 10), [มีคำขอ HTTPS\ ใหม่หรือไม่], shape: diamond),
|
||||
edge((0, 10), (-2, 10), "-|>", [ไม่มี], label-pos: 10%),
|
||||
edge((0, 9), (1, 9), "-|>", [มี], label-anchor: "center", label-sep: -8pt),
|
||||
|
||||
node((1, 10), [ประมวลผลคำขอ HTTPS]),
|
||||
edge((1, 10), (1, 11), (-2, 11), (-2, 10), "-|>"),
|
||||
|
||||
node((-2, 10), shape: circle, radius: 1em),
|
||||
edge((-2, 10), (-2, 6), (0, 6), "-|>"),
|
||||
)
|
||||
|
||||
#pagebreak()
|
||||
#set par(leading: 1em)
|
||||
|
||||
== การออกแบบ
|
||||
|
||||
== วัสดุอุปกรณ์
|
||||
|
||||
+ บอร์ด ESP32 (NodeMCU)
|
||||
+ กล่องพลาสติก
|
||||
+ Buzzer
|
||||
+ เซนเซอร์ PIR
|
||||
+ เซนเซอร์ NFC 2 ชิ้น
|
||||
|
||||
== ขั้นตอนการประกอบ
|
||||
|
||||
=== การติดตั้งอุปกรณ์
|
||||
|
||||
=== การเขียนเฟิร์มแวร์
|
||||
|
||||
โครงงานนี้ใช้ซอฟต์แวร์ PlatformIO ในการสร้างและจัดการโปรเจกต์เฟิร์มแวร์
|
||||
โดยหากต้องการเพียงแค่เขียนเฟิร์มแวร์ลงไปยังบอร์ด ESP32 คุณจำเป็นต้องใช้ซอฟต์แวร์หลัก ๆ คือ
|
||||
PlatformIO Core และ Git (ไม่จำเป็น แต่เพื่อความสะดวกสบาย)
|
||||
|
||||
อย่างไรก็ตาม PlatformIO จำเป็นต้องใช้ Python เวอร์ชัน 3.6 ขึ้นไปด้วยเช่นกัน
|
||||
ดังนั้นคุณจำเป็นต้องติดตั้ง Python ด้วยหากคุณยังไม่มี
|
||||
|
||||
ในขั้นตอนแรก โปรดเปิดเทอร์มินัลของคุณ ซึ่งโดยทั่วไปแล้วคุณสามารถค้นหาแอพลิเคชัน "Terminal" ได้เลย
|
||||
โดยบน Windows 10 เวอร์ชั่นใหม่ ๆ และ Windows 11 จะมาพร้อมกับแอพลิเคชัน Windows Terminal
|
||||
อย่างไรก็ตาม เมื่อเปิดแล้ว โปรดตรวจสอบให้แน่ใจว่าคุณกำลังใช้ PowerShell และไม่ใช่ Command
|
||||
Prompt
|
||||
|
||||
โดยในปัจจุบัน Python เวอร์ชันล่าสุดคือ Python 3.14.2 โดยคุณสามารถติดตั้ง Python และ Git บน
|
||||
Windows ได้ด้วยการใช้คำสั่งต่อไปนี้
|
||||
|
||||
```sh
|
||||
winget install Python.Python.3.14 Git.Git -e -s winget
|
||||
```
|
||||
|
||||
สำหรับระบบปฏิบัติการอื่นนั้น โดยปกติแล้วจะไม่ต้องติดตั้ง Python
|
||||
เพิ่มเนื่องจากมีติดมากับระบบปฏิบัติการอยู่แล้ว อย่างไรก็ตาม บน Linux อาจต้องมีการติดตั้งการรองรับ
|
||||
Virtual Environment แยก โดยแต่ละระบบจะมีชื่อแพคเกจไม่เหมือนกัน โดยบน Debian, Fedora,
|
||||
และ Arch สามารถใช้คำสั่งต่อไปนี้ในการติดตั้งทั้ง Python Virtual Environment และ Git
|
||||
พร้อมกันได้
|
||||
|
||||
```sh
|
||||
# Debian
|
||||
sudo apt install python3-venv git
|
||||
# Fedora
|
||||
sudo dnf install python3-virtualenv git
|
||||
# Arch
|
||||
sudo pacman -S python-virtualenv git
|
||||
```
|
||||
|
||||
#pagebreak()
|
||||
|
||||
#show raw.where(block: true): set block(below: 2em)
|
||||
|
||||
==== การติดตั้ง PlatformIO Core ผ่านแพคเกจ
|
||||
|
||||
หากคุณใช้ Fedora Linux หรือ Arch Linux (หรือลูก ๆ ของมัน) คุณสามารถติดตั้งแพคเกจ
|
||||
PlatformIO ได้โดยตรง โดยมีคำสั่งดังนี้:
|
||||
|
||||
```sh
|
||||
# Fedora Linux
|
||||
sudo dnf install platformio
|
||||
# Arch Linux
|
||||
sudo pacman -S platformio-core
|
||||
```
|
||||
|
||||
หากคุณติดตั้งแพคเกจ Fedora นั้นแล้ว คุณไม่จำเป็นที่จะต้องติดตั้งกฎ udev ด้วยตนเอง
|
||||
(ที่จะถูกกล่าวถึงใน@pioudev)
|
||||
|
||||
หากคุณใช้ Arch คุณสามารถติดตั้งแพคเกจกฎ udev ได้โดยตรงโดยไม่ต้องดาวน์โหลดเอง
|
||||
|
||||
```sh
|
||||
sudo pacman -S --asdeps platformio-core-udev
|
||||
```
|
||||
|
||||
==== การติดตั้ง PlatformIO Core ผ่านสคริปต์
|
||||
|
||||
ถัดไป ในการติดตั้ง PlatformIO Core สามารถทำได้โดยการใช้สคริปต์ติดตั้ง โดยสำหรับ `curl`
|
||||
สามารถใช้คำสั่งนี้ได้:
|
||||
|
||||
```sh
|
||||
curl -fsSL -o get-platformio.py https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py
|
||||
```
|
||||
|
||||
หรือหากต้องการใช้ `wget`:
|
||||
|
||||
```sh
|
||||
wget -O get-platformio.py https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py
|
||||
```
|
||||
|
||||
หรือสำหรับ PowerShell, สามารถใช้ `iwr` (หรือชื่อเต็มคือ `Invoke-WebRequest`) ได้:
|
||||
|
||||
```sh
|
||||
iwr -OutFile get-platformio.py -Uri https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py
|
||||
```
|
||||
|
||||
(มีการเว้นบรรทัดใหม่เนื่องจากพื้นที่ไม่เพียงพอ โปรดอย่าเว้นบรรทัดเมื่อพิมพ์คำสั่งจริง)
|
||||
|
||||
แล้วดังนั้นจึงใช้คำสั่ง `python3 get-platformio.py` ในการรันสคริปต์ติดตั้งที่ได้ทำการดาวน์โหลดมา
|
||||
|
||||
โดยค่าเริ่มต้นแล้ว PlatformIO จะไม่เพิ่มตนเองเข้าไปยังตัวแปรสิ่งแวดล้อม PATH
|
||||
ซึ่งจำเป็นในการใช้คำสั่งจากที่ใหนก็ได้โดยไม่ต้องกล่าวถึงไฟล์พาธ
|
||||
|
||||
โดยสำหรับ Linux แล้วนั้น คุณต้องเพิ่ม `$HOME/.local/bin/` เข้าไปยัง PATH ของคุณ โดยหากคุณใช้
|
||||
Bash คุณสามารถแก้ไข `~/.bash_profile` และเพิ่มบรรทัดนี้เข้าไปได้:
|
||||
|
||||
```sh
|
||||
export PATH=$PATH:$HOME/.local/bin
|
||||
```
|
||||
|
||||
หากคุณใช้ Zsh สามารถใช้โคดเดียวกันได้ เพียงแต่คุณต้องแก้ไขไฟล์ `~/.zprofile` หรือ `~/.zshrc`
|
||||
แทน
|
||||
|
||||
โดยบน Windows มีขั้นตอนดังนี้:
|
||||
|
||||
+ กด Windows + R
|
||||
+ พิมพ์ `sysdm.cpl` และกด Enter
|
||||
+ ในหน้าต่าง *System Properties* คลิกไปยังแท็บ *Advanced*
|
||||
+ คลิกปุ่ม *Environment Variables*
|
||||
|
||||
หลังจากนั้น เลือกตัวแปร *Path* ในส่วน *User variables* แล้วจึงกด *Edit* แล้วเพิ่ม
|
||||
`%USERPROFILE%\.platformio\penv\Scripts\` เข้าไปในรายการ
|
||||
|
||||
==== 99-platformio-udev.rules <pioudev>
|
||||
|
||||
ผู้ใช้ Linux จำเป็นที่จะต้องติดตั้งกฎ udev โดยสามารถดูไฟล์กฎ udev เวอร์ชันล่าสุดได้ที่\
|
||||
https://raw.githubusercontent.com/platformio/platformio-core/develop/platformio/assets/system/99-platformio-udev.rules
|
||||
|
||||
*หมายเหตุ:* โปรดตรวจสอบว่า PID และ VID ของบอร์ดคุณอยู่ในไฟล์กฎนั้น โดยคุณสามารถดู PID/VID
|
||||
ของบอร์ดคุณได้ผ่านคำสั่ง `pio device list`
|
||||
|
||||
โดยไฟล์นั้นต้องถูกวางอยู่ที่ `/etc/udev/rules.d/99-platformio-udev.rules` (ตำแหน่งที่ดีที่สุด)
|
||||
หรือ `/lib/udev/rules.d/99-platformio-udev.rules` (อาจจำเป็นสำหรับบางระบบที่พัง)
|
||||
|
||||
โปรดใช้คำสั่งต่อไปนี้ในการดาวน์โหลดและวางไฟล์นั้นไว้ในสถานที่ที่ถูกต้อง:
|
||||
|
||||
```sh
|
||||
curl -fsSL https://raw.githubusercontent.com/platformio/platformio-core/develop/platformio/assets/system/99-platformio-udev.rules | sudo tee /etc/udev/rules.d/99-platformio-udev.rules
|
||||
```
|
||||
|
||||
หรือคุณก็สามารถดาวน์โหลดไฟล์นั้นด้วยตัวเองและคัดลอกมันไปในโฟลเดอร์ที่หมายได้เช่นกัน
|
||||
|
||||
```sh
|
||||
sudo cp 99-platformio-udev.rules /etc/udev/rules.d/99-platformio-udev.rules
|
||||
```
|
||||
|
||||
หลังจากนั้น รีสตาร์ทบริการ udev:
|
||||
|
||||
```sh
|
||||
sudo service udev restart
|
||||
```
|
||||
หรือ:
|
||||
```sh
|
||||
sudo udevadm control --reload-rules
|
||||
sudo udevadm trigger
|
||||
```
|
||||
|
||||
หลังจากติดตั้งไฟล์นี้แล้ว ถอดสายที่เชื่อมต่อระหว่างบอร์ดและคอมพิวเตอร์ของคุณแล้วเสียบมันใหม่
|
||||
|
||||
==== การดาวน์โหลดโปรเจกต์
|
||||
|
||||
สามารถใช้ Git ในการ clone โปรเจกต์ได้ด้วยคำสั่งต่อไปนี้:
|
||||
|
||||
```sh
|
||||
git clone https://gitskette.dailitation.xyz/linesofcodes/liteauth-firmware32.git
|
||||
```
|
||||
|
||||
โดย Git นั้นจะทำการโคลนโปรเจกต์ไปที่โฟลเดอร์ `liteauth-firmware32` เนื่องจากเป็นชื่อของ Git
|
||||
repository
|
||||
|
||||
หรือไปที่ https://gitskette.dailitation.xyz/linesofcodes/liteauth-firmware32
|
||||
และทำการคลิกปุ่ม *Code* แล้วกด *Download ZIP* หรือ *Download TAR.GZ*
|
||||
แล้วทำการแตกไฟล์ได้ตามปกติ
|
||||
|
||||
หลังจากนั้น ไปที่โฟลเดอร์ของคุณในเทอร์มินัลโดยใช้คำสั่ง `cd`
|
||||
|
||||
==== คำสั่ง PlatformIO เบื้องต้น
|
||||
|
||||
- `pio run --list-targets`: ดูรายการเป้าหมายคำสั่งรัน
|
||||
- `pio run upload`: รันเป้าหมายอัพโหลด ซึ่งนี่คือคำสั่งที่คุณควรจะใช้ในการเขียนเฟิร์มแวร์ลงบนบอร์ด
|
||||
- `pio device monitor`: เปิด Serial Monitor
|
||||
|
||||
*หมายเหตุ:* โปรดใช้คำสั่งประเภท `pio run` ในโฟลเดอร์ของโปรเจกต์
|
||||
|
||||
== การทดสอบ
|
||||
|
||||
== การวิเคราะห์ข้อมูล
|
||||
@@ -0,0 +1,266 @@
|
||||
#import "../PageTemplate.typ": *
|
||||
|
||||
== สร้างไฟล์แอปพลิเคชันด้วยตนเอง
|
||||
|
||||
#h(1.7em) โครงงานนี้ใช้แอปพลิเคชันที่สร้างขึ้นมาเอง โดยในการพัฒนาแอปพลิเคชัน
|
||||
อย่างน้อยต้องมีส่วนประกอบดังกล่าวก่อน
|
||||
|
||||
#set enum(indent: 1.7em)
|
||||
1. Flutter
|
||||
2. Git (ซึ่งคุณจะติดตั้งแล้วหากคุณทำตาม@writingFirmware)
|
||||
|
||||
#h(1.7em) อย่างไรก็ตาม Flutter มีข้อจำกัดว่า มีเพียง Android
|
||||
เท่านั้นที่ไม่ว่าแพลตฟอร์มไหนก็จะสามารถคอมไพล์ไฟล์ `.apk` ออกมาได้ ดังนั้น
|
||||
การสร้างแอปพลิเคชันสำหรับ Linux ต้องทำบน Linux เท่านั้น และการสร้างแอปพลิเคชันสำหรับ Windows
|
||||
ต้องทำบน Windows เท่านั้น
|
||||
|
||||
=== การติดตั้งโปรแกรมเขียนโคด
|
||||
|
||||
#iii จริง ๆ แล้วนั้น Flutter สามารถทำงานกับโปรแกรมเขียนโคดใดก็ได้
|
||||
แต่มีโปรแกรมเหล่านี้ที่อาจมีประสบการณ์การพัฒนาที่ดีกว่าโปรแกรมอื่น
|
||||
|
||||
#set enum(indent: 4.1em)
|
||||
1. Visual Studio Code (VS Code)
|
||||
2. Android Studio
|
||||
3. JetBrains IntelliJ
|
||||
4. Firebase Studio
|
||||
|
||||
#iii โครงงานนี้ใช้โปรแกรมเขียนโคด Android Studio เป็นหลักเนื่องจากแอปพลิเคชันโครงงานมี
|
||||
Android เป็นเป้าหมายหลัก และ Android SDK สามารถจัดการได้ง่ายกว่าใน Android Studio
|
||||
|
||||
#iii การติดตั้ง Flutter สามารถทำได้สองวิธีด้วยกัน คือการติดตั้งผ่าน Visual Studio Code (VS
|
||||
Code) และการติดตั้งด้วยตนเอง โดยหากต้องการใช้ VS Code เป็นโปรแกรมเขียนโคดอยู่แล้ว
|
||||
สามารถติดตั้งผ่าน VS Code ได้เลย แต่ก่อนอื่น ต้องทำการติดตั้งโปรแกรมและไลบรารีพื้นฐานที่จำเป็นสำหรับ
|
||||
Flutter ก่อน
|
||||
|
||||
=== การติดตั้งโปรแกรมและไลบรารีที่จำเป็น
|
||||
|
||||
1. สำหรับ Windows ติดตั้ง Git สำหรับ Windows ซึ่งคุณสามารถดูขั้นตอนการติดตั้งได้ที่
|
||||
https://git-scm.com/install/windows หรือเพียงแค่ใช้คำสั่งด้านล่าง
|
||||
#figure(
|
||||
```sh
|
||||
winget install --id Git.Git -e --source winget
|
||||
```,
|
||||
kind: image,
|
||||
caption: [คำสั่งในการติดตั้ง Git],
|
||||
)
|
||||
2. สำหรับ Linux โปรดดู@flLinuxDetails
|
||||
สำหรับรายละเอียดแพคเกจและคำสั่งที่ต้องใช้สำหรับระบบต่าง ๆ
|
||||
3. สำหรับ macOS ใช้คำสั่งต่อไปนี้ในการติดตั้งเครื่องมือ Xcode ต่าง ๆ รวมถึง Git
|
||||
#figure(
|
||||
```sh
|
||||
xcode-select --install
|
||||
```,
|
||||
kind: image,
|
||||
caption: [คำสั่งในการติดตั้งเครื่องมือ Xcode],
|
||||
)
|
||||
|
||||
=== การติดตั้งผ่าน Visual Studio Code
|
||||
|
||||
#[
|
||||
#set enum(indent: 4.1em)
|
||||
1. เปิด VSCode
|
||||
2. ติดตั้งส่วนขยาย Flutter ซึ่งอยู่ภายใต้ ID `Dart-Code.flutter` ทั้งบน Visual Studio
|
||||
Marketplace และ OpenVSX
|
||||
3. ติดตั้ง Flutter ด้วย VS Code
|
||||
|
||||
#listy(
|
||||
indent: 5.5em,
|
||||
numbering: thai-numbering,
|
||||
[เปิด Command Palette ด้วยเมนู _View > Command Palette_ หรือกด Ctrl + Shift +
|
||||
P],
|
||||
[ใน Command Palette พิมพ์ `flutter`],
|
||||
[เลือก _Flutter: New Project_],
|
||||
[VS Code จะให้คุณเลือก Flutter SDK บนคอมพิวเตอร์ของคุณ เลือก _Download SDK_],
|
||||
[เมือหน้าไดอะลอก _Select Folder for Flutter SDK_ แสดงขึ้น เลือกสถานที่ที่คุณอยากติดตั้ง
|
||||
Flutter],
|
||||
[คลิก _Clone Flutter_ โดยในระหว่างการดาวน์โหลด VS Code จะแสดงการแจ้งเตือนนี้
|
||||
```
|
||||
Downloading the Flutter SDK. This may take a few minutes.
|
||||
```
|
||||
การดาวน์โหลดนี้จะใช้เวลาสองสามนาที หากคุณเชื่อว่าการดาวน์โหลดหยุดชะงัก คุณสามารถคลิก
|
||||
_Cancel_ แล้วเริ่มต้นการติดตั้งใหม่ได้],
|
||||
[คลิก _Add SDK to PATH_ และเมื่อเสร็จสิ้น จะมีการแจ้งเตือน
|
||||
```
|
||||
The Flutter SDK was added to your PATH
|
||||
```],
|
||||
[VS Code อาจแสดงการแจ้งเตือนเกี่ยวกับการเก็บข้อมูลของ Google หากคุณยินยอม คลิก _OK_],
|
||||
[เพื่อความแน่ใจ กรุณาปิดเทอร์มินัลทุกหน้าต่างหรือรีสตาร์ท VS Code เพื่อให้แน่ใจว่า Flutter
|
||||
จะสามารถใช้ผ่านเทอร์มินัลได้],
|
||||
)
|
||||
|
||||
4. เมื่อเสร็จสิ้น ใช้คำสั่ง `flutter doctor -v` ในเทอร์มินัลที่คุณเลือกเพื่อตรวจสอบการติดตั้ง
|
||||
Flutter ของคุณ หากคำสั่งไม่เจอหรือเกิดข้อผิดพลาดขึ้น ตรวจสอบ
|
||||
https://docs.flutter.dev/install/troubleshoot สำหรับข้อมูลเพิ่มเติม
|
||||
]
|
||||
|
||||
=== การติดตั้งด้วยตนเอง
|
||||
|
||||
#iii แนะนำให้ทำตาม https://docs.flutter.dev/install/manual#install-flutter
|
||||
เนื่องจากกระบวนการนี้ต้องใช้ข้อมูลที่ใหม่ล่าสุด
|
||||
|
||||
#[
|
||||
#set enum(indent: 4.1em)
|
||||
1. ดาวน์โหลด Flutter (สามารถหาปุ่มดาวน์โหลดได้จากลิงก์ด้านบน)
|
||||
2. สร้างโฟลเดอร์สำหรับเก็บ Flutter SDK
|
||||
3. ทำการแตกไฟล์ที่ดาวน์โหลดมา
|
||||
4. เพิ่ม Flutter เข้าไปยัง PATH ของคุณ (วิธีการขึ้นอยู่กับระบบปฏิบัติการ)
|
||||
5. ยืนยันความถูกต้องของการติดตั้งของคุณด้วยคำสั่ง `flutter doctor -v`
|
||||
]
|
||||
|
||||
=== ข้อมูลเฉพาะแพลตฟอร์ม
|
||||
|
||||
==== Android <flAndroid>
|
||||
|
||||
#h(7.3em) ในการพัฒนาแอปพลิเคชัน Android โดยใช้เฟรมเวิร์ก Flutter
|
||||
จำเป็นต้องใช้ส่วนประกอบเครื่องมือพัฒนา Android ดังนี้
|
||||
|
||||
#[
|
||||
#set enum(indent: 7.3em)
|
||||
1. Android SDK (API Level 36 ณ เวลาที่พิมพ์)
|
||||
2. Android SDK Build-Tools
|
||||
3. Android SDK Command-line Tools
|
||||
4. Android SDK Platform-Tools
|
||||
5. Android Emulator (ไม่บังคับ)
|
||||
]
|
||||
|
||||
โดยแนะนำให้จัดการและติดตั้งเครื่องมือเหล่านี้ผ่าน Android Studio
|
||||
|
||||
#h(7.3em) ในการติดตั้ง Android SDK ควรติดตั้ง Android SDK
|
||||
ล่าสุดถึงแม้ว่าอุปกรณ์ของคุณจะใช้เวอร์ชันที่เก่ากว่านั้น
|
||||
เพื่อความมั่นใจว่าแอปพลิเคชันจะสามารถใช้กับอุปกรณ์ที่ใหม่ล่าสุดได้
|
||||
|
||||
#h(7.3em) แอปพลิเคชัน Android จะมี SDK/API level เป้าหมาย (Target SDK/API level) และ
|
||||
SDK/API level ขั้นต่ำ (Minimum SDK/API level) โครงงานนี้ ณ เวลาที่พิมพ์ ใช้ API level
|
||||
เป้าหมาย 36 (Android 16) และ API level ขั้นต่ำ 24 (Android 7) ซึ่งรวมกันแล้ว
|
||||
แอปพลิเคชัน#jb Android จะสามารถติดตั้งได้บนระบบตั้งแต่ API level ขั้นต่ำจนถึง API level
|
||||
เป้าหมาย หรือก็คือ แอปพลิเคชันในโครงงานนี้สามารถติดตั้งได้ตั้งแต่บนระบบ Android 7 ถึง Android 16
|
||||
นั่นเอง
|
||||
|
||||
===== Java/Kotlin
|
||||
|
||||
#h(11.3em) Java และ Kotlin เป็นภาษาสำคัญสำหรับการพัฒนาแอปพลิเคชัน Android ถึงอย่างไรก็ตาม
|
||||
แอปพลิเคชัน Flutter นั้นถูกเขียนด้วยภาษา Dart แต่ยังจำเป็นต้องมีโคด Java และ Kotlin
|
||||
เล็กน้อยเพื่อเริ่มต้นแอปพลิเคชัน Flutter
|
||||
|
||||
#h(11.3em) โดยปกติแล้ว Flutter จะสร้างโคดพื้นฐานขึ้นมาให้สำหรับการเริ่มแอปพลิเคชันแบบพื้นฐาน
|
||||
ดังนั้นจึงไม่จำเป็นต้องมีการเขียนโคด Java หรือ Kotlin เอง แต่ในบางกรณี
|
||||
อาจต้องเขียนโคดเพิ่มเองหากมีความต้องการเข้าถึงฟีเจอร์พื้นฐานระบบที่ Flutter ไม่มี API
|
||||
เพื่อให้เข้าถึงได้และไม่มีแพคเกจเพื่อรองรับฟีเจอร์ที่ต้องการ
|
||||
|
||||
#h(11.3em) โครงการนี้ใช้ Java 21 (JetBrains Runtime/Azul Zulu OpenJDK)
|
||||
เป็นหลักในการทำงานกับ Gradle แต่แอปพลิเคชัน Android ที่ผลิตออกมานั้น
|
||||
เพื่อให้เข้ากับเวอร์ชันที่เก่ากว่าของระบบปฏิบัติการได้ ใช้ Java 11
|
||||
|
||||
===== Gradle
|
||||
|
||||
#h(11.3em) Gradle เป็นเครื่องมือสร้างระบบอัตโนมัติสำหรับการพัฒนาซอฟต์แวร์หลายภาษา
|
||||
จัดการงานต่าง ๆ เช่น การคอมไพล์ การแพ็คเกจ การทดสอบ การปรับใช้ และการเผยแพร่ ภาษาที่รองรับ
|
||||
ได้แก่ Java (รวมถึงภาษา Kotlin, Groovy, Scala ที่ใช้ JDK), C/C++ และ JavaScript Gradle
|
||||
พัฒนาต่อยอดจากแนวคิดของ Apache Ant และ Apache Maven และนำเสนอภาษาเฉพาะโดเมนที่ใช้
|
||||
Groovy และ Kotlin ซึ่งต่างจากการกำหนดค่าโครงการที่ใช้ XML ที่ Maven ใช้ Gradle
|
||||
ใช้กราฟแบบอะไซคลิกกำกับทิศทางเพื่อจัดการการอ้างอิง กราฟนี้ใช้เพื่อกำหนดลำดับของงานที่ควรดำเนินการ
|
||||
Gradle ทำงานบน Java Virtual Machine
|
||||
|
||||
#h(11.3em) Gradle คือเครื่องมือหลักที่ใช้ในการจัดการโปรเจกต์ Java ส่วนใหญ่ รวมถึงโปรเจกต์
|
||||
Android โดยในโครงการนี้ จะใช้ Gradle เวอร์ชัน 8.14.3 เป็นหลัก
|
||||
|
||||
#h(11.3em) โดยปกติแล้ว ผู้พัฒนานั้นไม่มีความจำเป็นที่จะต้องแตะต้อง Gradle ด้วยตนเอง และ Flutter
|
||||
จะทำการจัดการเอง แต่หากมีความจำเป็นต้องใช้คำสั่ง Gradle ด้วยตนเอง จะมีสคริปต์ `gradlew` (หรือ
|
||||
`gradlew.bat` สำหรับผู้ใช้ Windows) ภายในโฟลเดอร์ `android` ของโปรเจกต์ Flutter
|
||||
เสมอเพื่อเรียกใช้ Gradle ที่ถูกดาวน์โหลดมาสำหรับโปรเจกต์นั้น ๆ
|
||||
|
||||
==== Linux <flLinuxDetails>
|
||||
|
||||
#h(7.3em) เช่นเดียวกับ Android ที่กล่าวไปข้างต้น Flutter
|
||||
มีการสร้างโคดสำหรับการเปิดแอปพลิเคชันแบบพื้นฐาน แต่สำหรับ Linux แล้วนั้น Flutter ใช้โคด C++
|
||||
และเฟรมเวิร์ก CMake ในการสร้างรากฐานของแอปพลิเคชัน
|
||||
|
||||
#h(7.3em) ในการพัฒนาแอปพลิเคชันสำหรับ Linux ต้องติดตั้งโปรแกรมเพิ่มเติม#jb (build
|
||||
dependencies) ขยายความคือ ด้านบนคือสิ่งที่จำเป็นหากมีระบบอื่นเป็นเป้าหมาย
|
||||
แต่หากต้องการพัฒนาแอปพลิเคชัน Linux ต้องติดตั้งโปรแกรมในรายการหน้าถัดไปเพิ่ม
|
||||
|
||||
#pagebreak()
|
||||
|
||||
#[
|
||||
#set enum(indent: 7.3em)
|
||||
1. GTK 3 (ไลบรารีสำหรับการพัฒนา)
|
||||
2. pkg-config
|
||||
3. ไลบรารี GNU Standard C++ v3
|
||||
4. Clang
|
||||
5. CMake
|
||||
6. Ninja
|
||||
]
|
||||
|
||||
#h(7.3em) การติดตั้งไลบรารีและโปรแกรมที่กล่าวไปข้างต้นจะแตกต่างกันไปแต่ละการแจกจ่าย Linux และ
|
||||
Flutter ใช้ไลบรารีพื้นฐานดังกล่าวในการทำงานของแอปพลิเคชัน (runtime dependencies)
|
||||
|
||||
#[
|
||||
#set enum(indent: 7.3em)
|
||||
1. GTK 3
|
||||
2. blkid
|
||||
3. LZMA
|
||||
]
|
||||
|
||||
แต่โดยทั่วไปแล้ว ไลบรารีเหล่านี้ควรถูกติดตั้งมาอยู่แล้วหากคุณใช้ graphical desktop ทั่วไป
|
||||
|
||||
===== Debian
|
||||
|
||||
#afigure(
|
||||
```sh
|
||||
# Development dependencies:
|
||||
sudo apt install curl git unzip xz-utils zip libglu1-mesa
|
||||
|
||||
# Linux build dependencies:
|
||||
sudo apt install clang cmake ninja-build pkg-config libgtk-3-dev libstdc++-12-dev
|
||||
|
||||
# Runtime dependencies:
|
||||
sudo apt install libgtk-3-0 libblkid1 liblzma5
|
||||
```,
|
||||
kind: image,
|
||||
caption: [คำสั่งในการติดตั้งรายการแพคเกจต่าง ๆ บน Debian],
|
||||
)
|
||||
|
||||
#v(0.5em)
|
||||
|
||||
===== Fedora Linux
|
||||
|
||||
#afigure(
|
||||
```sh
|
||||
# Development dependencies:
|
||||
sudo dnf install curl git unzip xz zip mesa-libglu
|
||||
|
||||
# Linux build dependencies:
|
||||
sudo dnf install clang cmake ninja-build pkgconf gtk3
|
||||
|
||||
# Runtime dependencies:
|
||||
sudo dnf install gtk3 libblkid xz
|
||||
```,
|
||||
kind: image,
|
||||
caption: [คำสั่งในการติดตั้งรายการแพคเกจต่าง ๆ บน Fedora Linux],
|
||||
)
|
||||
|
||||
===== Arch Linux
|
||||
|
||||
#afigure(
|
||||
```sh
|
||||
# Development dependencies:
|
||||
sudo pacman -S --needed curl git unzip xz zip glu
|
||||
|
||||
# Linux build dependencies:
|
||||
sudo pacman -S --needed clang cmake ninja pkgconf gtk3
|
||||
|
||||
# Runtime dependencies:
|
||||
sudo pacman -S --needed util-linux-libs xz gtk3
|
||||
```,
|
||||
kind: image,
|
||||
caption: [คำสั่งในการติดตั้งรายการแพคเกจต่าง ๆ บน Arch Linux],
|
||||
)
|
||||
|
||||
#v(0.5em)
|
||||
|
||||
==== macOS/iOS
|
||||
|
||||
#h(7.3em) การพัฒนาแอปพลิเคชันสำหรับ macOS และ iOS นั้นต้องทำบน macOS
|
||||
เท่านั้นและจำเป็นต้องพึ่งพาเครื่องมือ Xcode แต่เนื่องจากในโครงงานนี้ไม่มีผู้ใช้ macOS
|
||||
จึงไม่สามารถสร้างไบนารีสำหรับ macOS และ iOS ออกมาได้ และไม่ใช่เป้าหมายของโครงงานนี้เช่นกัน
|
||||
@@ -0,0 +1,474 @@
|
||||
#import "../PageTemplate.typ": *
|
||||
#import "@preview/tiaoma:0.3.0"
|
||||
#import "@preview/fletcher:0.5.8" as fletcher: diagram, edge, node
|
||||
#import fletcher.shapes: circle, diamond, pill
|
||||
#show: chapter-page
|
||||
#set heading(numbering: "บทที่ 1")
|
||||
|
||||
#heading([#linebreak()วิธีการดำเนินโครงงาน])
|
||||
#set heading(numbering: "1.1")
|
||||
|
||||
#i ในการดำเนินการศึกษาครั้งนี้
|
||||
คณะผู้จัดทำโครงงานได้ศึกษาข้อมูลเบื้องต้นในการสร้างเครื่องยืนยันตัวตนด้วย NFC
|
||||
และได้ดำเนินการตามขั้นตอนนี้
|
||||
|
||||
#set enum(indent: 3em)
|
||||
1. วางแผนการดำเนินงาน
|
||||
2. การออกแบบ
|
||||
3. วัสดุอุปกรณ์
|
||||
4. ขั้นตอนการประกอบ
|
||||
5. การทดลอง
|
||||
6. การวิเคราะห์ข้อมูล
|
||||
|
||||
#show heading.where(level: 3): it => {
|
||||
block(
|
||||
it,
|
||||
inset: (left: 1.7em),
|
||||
)
|
||||
}
|
||||
#show heading.where(level: 4): it => {
|
||||
block(
|
||||
it,
|
||||
inset: (left: 4.1em),
|
||||
)
|
||||
}
|
||||
#show heading.where(level: 5): it => {
|
||||
block(
|
||||
it,
|
||||
inset: (left: 7.3em),
|
||||
)
|
||||
}
|
||||
|
||||
== วางแผนการดำเนินงาน
|
||||
|
||||
#show table.cell.where(y: 1): strong
|
||||
#set par(leading: 0.5em)
|
||||
|
||||
#let arrow = [
|
||||
#place(
|
||||
left + horizon,
|
||||
text(weight: "bold", size: 14pt)[#sym.arrow.l],
|
||||
dx: -5pt,
|
||||
dy: -0.7pt,
|
||||
)
|
||||
#place(
|
||||
horizon,
|
||||
line(length: 100%, stroke: (thickness: 1pt)),
|
||||
dx: 0pt,
|
||||
dy: 0pt,
|
||||
)
|
||||
#place(
|
||||
right + horizon,
|
||||
text(weight: "bold", size: 14pt)[#sym.arrow.r],
|
||||
dx: 5pt,
|
||||
dy: -0.7pt,
|
||||
)
|
||||
]
|
||||
|
||||
=== แผนขั้นตอนและวิธีการดำเนินงาน
|
||||
|
||||
ตาราง 3.1 ระยะเวลาการดำเนินงาน
|
||||
#v(0.5em, weak: true)
|
||||
|
||||
#table(
|
||||
columns: (2fr, 1fr, 1fr, 1fr, 1fr, 1fr),
|
||||
align: (
|
||||
left + horizon,
|
||||
center,
|
||||
center,
|
||||
center,
|
||||
center,
|
||||
center,
|
||||
),
|
||||
table.header(
|
||||
table.cell(
|
||||
[ขั้นตอนการดำเนินการ],
|
||||
rowspan: 2,
|
||||
),
|
||||
table.cell(
|
||||
[พ.ศ.2568],
|
||||
colspan: 3,
|
||||
),
|
||||
table.cell(
|
||||
[พ.ศ.2569],
|
||||
colspan: 2,
|
||||
),
|
||||
[ต.ค.],
|
||||
[พ.ย.],
|
||||
[ธ.ค.],
|
||||
[ม.ค.],
|
||||
[ก.พ.],
|
||||
),
|
||||
[ศึกษาค้นคว้าข้อมูล],
|
||||
table.cell(arrow, colspan: 3),
|
||||
[],
|
||||
[],
|
||||
[เสนอหัวข้อ], arrow, [], [], [], [],
|
||||
[เสนอครั้งที่ 1], [], arrow, [], [], [],
|
||||
[ออกแบบและสร้าง], [], table.cell(arrow, colspan: 3), [],
|
||||
[จัดซื้ออุปกรณ์ทดลอง],
|
||||
[],
|
||||
table.cell(arrow, colspan: 3),
|
||||
[],
|
||||
[ทดลองการทำงาน], [], [], table.cell(arrow, colspan: 2), [],
|
||||
[ปรับปรุงแก้ไข], [], [], [], [], arrow,
|
||||
[เสนอครั้งที่ 2], [], [], [], arrow, [],
|
||||
[จัดทำรูปเล่ม], table.cell(arrow, colspan: 5),
|
||||
[นำเสนอโครงงาน], [], [], [], [], [],
|
||||
)
|
||||
|
||||
#show: page-theme
|
||||
#set par(leading: 0.5em)
|
||||
|
||||
=== ผังการดำเนินงาน
|
||||
|
||||
#include "ProjectFlowchart.typ"
|
||||
|
||||
#pagebreak()
|
||||
|
||||
=== ผังการทำงาน
|
||||
|
||||
#include "ProductFlowchart.typ"
|
||||
|
||||
#pagebreak()
|
||||
#set par(leading: 1em)
|
||||
|
||||
== การออกแบบ
|
||||
|
||||
#figure(
|
||||
image(
|
||||
"imgs/ProjectDraft_Modules.png",
|
||||
alt: "ภาพแสดงการโมเดลโครงงานซึ่งประกอบไปด้วยสามส่วน",
|
||||
width: 5in,
|
||||
),
|
||||
caption: [การออกแบบโครงสร้างเครื่องยืนยันตัวตนด้วย NFC],
|
||||
)
|
||||
|
||||
#v(2em)
|
||||
|
||||
== วัสดุอุปกรณ์
|
||||
|
||||
#set enum(indent: 1.7em)
|
||||
|
||||
1. บอร์ด ESP32 (NodeMCU)
|
||||
2. กล่องพลาสติก
|
||||
3. บัซเซอร์ (Buzzer)
|
||||
4. เซนเซอร์ NFC (PN532)
|
||||
// 5. เซนเซอร์ PIR
|
||||
|
||||
== ขั้นตอนการประกอบ
|
||||
|
||||
=== การติดตั้งอุปกรณ์
|
||||
|
||||
#h(4.1em) โครงงานแบ่งออกเป็น 3 โมดูล
|
||||
|
||||
#set enum(indent: 4.1em)
|
||||
1. โมดูลบอร์ด ESP32
|
||||
2. โมดูลเซนเซอร์ NFC
|
||||
// 3. โมดูลเซนเซอร์ PIR
|
||||
|
||||
==== โมดูลบอร์ด ESP32
|
||||
|
||||
#h(7.3em) ทำการเจาะรู 2 รูสำหรับสายและร้อยสายเข้าไปในกล่อง
|
||||
|
||||
#figure(
|
||||
image(
|
||||
"imgs/MainModuleInternal.jpg",
|
||||
alt: "ภายในกล่องโมดูลหลัก มีบอร์ดอยู่ภายใน",
|
||||
height: 2in,
|
||||
),
|
||||
caption: [ภายในกล่องโมดูล ESP32],
|
||||
)
|
||||
|
||||
#v(2em)
|
||||
|
||||
==== โมดูลเซนเซอร์ NFC
|
||||
|
||||
#h(7.3em) ดำเนินการเจาะรูบริเวณตัวกล่องเพื่อใช้เป็นช่องสำหรับสายไฟ
|
||||
จากนั้นนำสายไฟร้อยผ่านช่องดังกล่าวและต่อเข้ากับเซนเซอร์ NFC ให้เรียบร้อย
|
||||
|
||||
#figure(
|
||||
image(
|
||||
"imgs/NFCSensor_cropped.jpg",
|
||||
alt: "ภายกล่องโมดูลเซนเซอร์ NFC",
|
||||
height: 2in,
|
||||
),
|
||||
caption: [โมดูลเซนเซอร์ NFC],
|
||||
)
|
||||
#v(1.5em)
|
||||
|
||||
// ==== โมดูลเซนเซอร์ PIR
|
||||
|
||||
=== การเขียนเฟิร์มแวร์ <writingFirmware>
|
||||
|
||||
#iii โครงงานนี้ใช้ซอฟต์แวร์ PlatformIO ในการสร้างและจัดการโปรเจกต์เฟิร์มแวร์
|
||||
โดยหากต้องการเพียงแค่เขียนเฟิร์มแวร์ลงไปยังบอร์ด ESP32 คุณจำเป็นต้องใช้ซอฟต์แวร์หลัก ๆ คือ
|
||||
PlatformIO Core และ Git (ไม่จำเป็น แต่เพื่อความสะดวกสบาย) อย่างไรก็ตาม PlatformIO
|
||||
จำเป็นต้องใช้ Python เวอร์ชัน 3.6 ขึ้นไปด้วยเช่นกัน ดังนั้นคุณจำเป็นต้องติดตั้ง Python
|
||||
ด้วยหากคุณยังไม่มี
|
||||
|
||||
#iii ในขั้นตอนแรก โปรดเปิดเทอร์มินัลของคุณ ซึ่งโดยทั่วไปแล้วคุณสามารถค้นหาแอปพลิเคชัน#jb
|
||||
"Terminal" ได้เลย โดยบน Windows 10 เวอร์ชั่นใหม่ ๆ และ Windows 11 จะมาพร้อมกับแอปพลิเคชัน
|
||||
Windows Terminal อย่างไรก็ตาม เมื่อเปิดแล้ว โปรดตรวจสอบให้แน่ใจว่าคุณกำลังใช้ PowerShell
|
||||
และไม่ใช่ Command Prompt
|
||||
|
||||
#iii โดยในปัจจุบัน Python เวอร์ชันล่าสุดคือ Python 3.14.2 โดยคุณสามารถติดตั้ง Python และ Git
|
||||
บน Windows ได้ด้วยการใช้คำสั่งต่อไปนี้
|
||||
|
||||
#figure(
|
||||
```sh
|
||||
winget install Python.Python.3.14 Git.Git -e -s winget
|
||||
```,
|
||||
kind: image,
|
||||
caption: [คำสั่งในการติดตั้ง Python 3.14 และ Git],
|
||||
)
|
||||
|
||||
#v(1.5em)
|
||||
|
||||
#iii สำหรับระบบปฏิบัติการอื่นนั้น โดยปกติแล้วจะไม่ต้องติดตั้ง Python
|
||||
เพิ่มเนื่องจากมีติดมากับระบบปฏิบัติการอยู่แล้ว อย่างไรก็ตาม บน Linux อาจต้องมีการติดตั้งการรองรับ
|
||||
Virtual Environment แยก โดยแต่ละระบบจะมีชื่อแพคเกจไม่เหมือนกัน โดยบน Debian, Fedora,
|
||||
และ Arch สามารถใช้คำสั่งต่อไปนี้ในการติดตั้งทั้ง Python Virtual Environment และ Git
|
||||
พร้อมกันได้
|
||||
|
||||
#show raw.where(block: true): set block(below: 2em)
|
||||
#figure(
|
||||
```sh
|
||||
# Debian
|
||||
sudo apt install python3-venv git
|
||||
# Fedora
|
||||
sudo dnf install python3-virtualenv git
|
||||
# Arch
|
||||
sudo pacman -S python-virtualenv git
|
||||
```,
|
||||
kind: image,
|
||||
caption: [คำสั่งในการติดตั้ง Virtual Environment และ Git บนการแจกจ่าย Linux ต่าง ๆ],
|
||||
)
|
||||
|
||||
#v(1.5em)
|
||||
|
||||
#pagebreak()
|
||||
|
||||
==== การติดตั้ง PlatformIO Core ผ่านแพคเกจ
|
||||
|
||||
#h(7.3em) หากคุณใช้ Fedora Linux หรือ Arch Linux (หรือลูก ๆ ของมัน) คุณสามารถติดตั้งแพคเกจ
|
||||
PlatformIO ได้โดยตรง โดยมีคำสั่งดังนี้
|
||||
|
||||
#figure(
|
||||
```sh
|
||||
# Fedora Linux
|
||||
sudo dnf install platformio
|
||||
# Arch Linux
|
||||
sudo pacman -S platformio-core
|
||||
```,
|
||||
kind: image,
|
||||
caption: [คำสั่งในการติดตั้ง PlatformIO Core บน Fedora และ Arch Linux],
|
||||
)
|
||||
|
||||
#v(1.5em)
|
||||
|
||||
#set enum(indent: 7.3em)
|
||||
1. หากคุณติดตั้งแพคเกจ Fedora นั้นแล้ว คุณไม่จำเป็นที่จะต้องติดตั้งกฎ udev ด้วยตนเอง
|
||||
(ที่จะถูกกล่าวถึงใน@pioudev)
|
||||
|
||||
2. หากคุณใช้ Arch คุณสามารถติดตั้งแพคเกจกฎ udev ได้โดยตรงโดยไม่ต้องดาวน์โหลดเอง
|
||||
#figure(
|
||||
```sh
|
||||
sudo pacman -S --asdeps platformio-core-udev
|
||||
```,
|
||||
kind: image,
|
||||
caption: [คำสั่งในการติดตั้งกฎ udev ของ PlatformIO บน Arch Linux],
|
||||
)
|
||||
|
||||
#v(2.5em)
|
||||
|
||||
==== การติดตั้ง PlatformIO Core ผ่านสคริปต์
|
||||
|
||||
#h(7.3em) ถัดไป ในการติดตั้ง PlatformIO Core สามารถทำได้โดยการใช้สคริปต์ติดตั้ง โดยสำหรับ
|
||||
`curl` สามารถใช้คำสั่งนี้ได้
|
||||
|
||||
#figure(
|
||||
```sh
|
||||
curl -fsSL -o get-platformio.py https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py
|
||||
```,
|
||||
kind: image,
|
||||
caption: [คำสั่ง `curl` ที่ใช้ในการดาวน์โหลดสคริปต์ติดตั้ง PlatformIO],
|
||||
)
|
||||
|
||||
#pagebreak()
|
||||
|
||||
#h(7.3em) หรือหากต้องการใช้ `wget`
|
||||
|
||||
#figure(
|
||||
```sh
|
||||
wget -O get-platformio.py https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py
|
||||
```,
|
||||
kind: image,
|
||||
caption: [คำสั่ง `wget` ที่ใช้ในการดาวน์โหลดสคริปต์ติดตั้ง PlatformIO],
|
||||
)
|
||||
|
||||
#v(1.5em)
|
||||
|
||||
#h(7.3em) หรือสำหรับ PowerShell, สามารถใช้ `iwr` (หรือชื่อเต็มคือ `Invoke-WebRequest`)
|
||||
ได้
|
||||
|
||||
#figure(
|
||||
```sh
|
||||
iwr -OutFile get-platformio.py -Uri https://raw.githubusercontent.com/platformio/platformio-core-installer/master/get-platformio.py
|
||||
```,
|
||||
kind: image,
|
||||
caption: [คำสั่ง `iwr` ที่ใช้ในการดาวน์โหลดสคริปต์ติดตั้ง PlatformIO],
|
||||
)
|
||||
|
||||
#v(1.5em)
|
||||
|
||||
(มีการเว้นบรรทัดใหม่เนื่องจากพื้นที่ไม่เพียงพอ โปรดอย่าเว้นบรรทัดเมื่อพิมพ์คำสั่งจริง)
|
||||
|
||||
#h(7.3em) แล้วดังนั้นจึงใช้คำสั่ง `python3 get-platformio.py`
|
||||
ในการรันสคริปต์ติดตั้งที่ได้ทำการดาวน์โหลดมา โดยค่าเริ่มต้นแล้ว PlatformIO
|
||||
จะไม่เพิ่มตนเองเข้าไปยังตัวแปรสิ่งแวดล้อม PATH
|
||||
ซึ่งจำเป็นในการใช้คำสั่งจากที่ใหนก็ได้โดยไม่ต้องกล่าวถึงไฟล์พาธ
|
||||
|
||||
#h(7.3em) โดยสำหรับ Linux แล้วนั้น คุณต้องเพิ่ม `$HOME/.local/bin/` เข้าไปยัง PATH ของคุณ
|
||||
โดยหากคุณใช้ Bash คุณสามารถแก้ไข `~/.bash_profile` และเพิ่มบรรทัดนี้เข้าไปได้
|
||||
|
||||
#figure(
|
||||
```sh
|
||||
export PATH=$PATH:$HOME/.local/bin
|
||||
```,
|
||||
kind: image,
|
||||
caption: [โคดที่ต้องใช้ในการเพิ่ม `~/.local/bin` เข้า PATH],
|
||||
)
|
||||
|
||||
#v(1.5em)
|
||||
|
||||
#h(7.3em) หากคุณใช้ Zsh สามารถใช้โคดเดียวกันได้ เพียงแต่คุณต้องแก้ไขไฟล์ `~/.zprofile` หรือ
|
||||
`~/.zshrc` แทน
|
||||
|
||||
#h(7.3em) โดยบน Windows มีขั้นตอนดังนี้
|
||||
|
||||
#[
|
||||
#set enum(indent: 7.3em)
|
||||
1. กด Windows + R
|
||||
2. พิมพ์ `sysdm.cpl` และกด Enter
|
||||
3. ในหน้าต่าง _System Properties_ คลิกไปยังแท็บ _Advanced_
|
||||
4. คลิกปุ่ม _Environment Variables_
|
||||
]
|
||||
|
||||
#h(7.3em) จากนั้น เลือกตัวแปร _Path_ ในส่วน _User variables_ แล้วจึงกด _Edit_ แล้วเพิ่ม
|
||||
`%USERPROFILE%\.platformio\penv\Scripts\` เข้าไปในรายการ
|
||||
|
||||
==== 99-platformio-udev.rules <pioudev>
|
||||
|
||||
#h(7.3em) ผู้ใช้ Linux จำเป็นที่จะต้องติดตั้งกฎ udev โดยสามารถดูไฟล์กฎ udev เวอร์ชันล่าสุดได้ที่
|
||||
https://raw.githubusercontent.com/platformio/platformio-core/develop/platformio/assets/system/99-platformio-udev.rules
|
||||
และโปรดตรวจสอบว่า PID และ VID ของบอร์ดคุณอยู่ในไฟล์กฎนั้น โดยคุณสามารถดู PID/VID
|
||||
ของบอร์ดคุณได้ผ่านคำสั่ง `pio device list`
|
||||
|
||||
#h(7.3em) โดยไฟล์นั้นต้องถูกวางอยู่ที่ `/etc/udev/rules.d/99-platformio-udev.rules`
|
||||
(ตำแหน่งที่ดีที่สุด) หรือ `/lib/udev/rules.d/99-platformio-udev.rules`
|
||||
(อาจจำเป็นสำหรับบางระบบที่พัง)
|
||||
|
||||
#h(7.3em) โปรดใช้คำสั่งต่อไปนี้ในการดาวน์โหลดและวางไฟล์นั้นไว้ในสถานที่ที่ถูกต้อง
|
||||
|
||||
#figure(
|
||||
```sh
|
||||
curl -fsSL https://raw.githubusercontent.com/platformio/platformio-core/develop/platformio/assets/system/99-platformio-udev.rules | sudo tee /etc/udev/rules.d/99-platformio-udev.rules
|
||||
```,
|
||||
kind: image,
|
||||
caption: [คำสั่งในการดาวน์โหลดไฟล์กฎ `udev`],
|
||||
)
|
||||
|
||||
#v(1.5em)
|
||||
|
||||
#h(7.3em) หรือคุณก็สามารถดาวน์โหลดไฟล์นั้นด้วยตัวเองและคัดลอกมันไปในโฟลเดอร์ที่หมายได้เช่นกัน
|
||||
|
||||
#figure(
|
||||
```sh
|
||||
sudo cp 99-platformio-udev.rules /etc/udev/rules.d/99-platformio-udev.rules
|
||||
```,
|
||||
kind: image,
|
||||
caption: [คำสั่งในการคัดลอกไฟล์กฎ `udev` ไปยังสถานที่ที่ถูกต้อง],
|
||||
)
|
||||
|
||||
#v(1.5em)
|
||||
|
||||
#h(7.3em) หลังจากนั้น รีสตาร์ทบริการ udev
|
||||
|
||||
#figure(
|
||||
```sh
|
||||
sudo service udev restart
|
||||
```,
|
||||
kind: image,
|
||||
caption: [คำสั่งในการรีสตาร์ทบริการ `udev`],
|
||||
)
|
||||
|
||||
#v(1.5em)
|
||||
|
||||
#h(7.3em) หรือทำการรีโหลดและทริกเกอร์กฎ
|
||||
|
||||
#figure(
|
||||
```sh
|
||||
sudo udevadm control --reload-rules
|
||||
sudo udevadm trigger
|
||||
```,
|
||||
kind: image,
|
||||
caption: [คำสั่งในการรีโหลดกฎ `udev`],
|
||||
)
|
||||
|
||||
#v(1.5em)
|
||||
|
||||
#h(7.3em) หลังจากติดตั้งไฟล์นี้แล้ว ถอดสายที่เชื่อมต่อระหว่างบอร์ดและคอมพิวเตอร์ของคุณแล้วเสียบมันใหม่
|
||||
|
||||
==== การดาวน์โหลดโปรเจกต์
|
||||
|
||||
#h(7.3em) สามารถใช้ Git ในการ clone โปรเจกต์ได้ด้วยคำสั่งต่อไปนี้
|
||||
|
||||
#figure(
|
||||
```sh
|
||||
git clone https://gitskette.dailitation.xyz/linesofcodes/liteauth-firmware32.git
|
||||
```,
|
||||
kind: image,
|
||||
caption: [คำสั่งในการโคลนโคดสำหรับเฟิร์มแวร์],
|
||||
)
|
||||
|
||||
#v(1.5em)
|
||||
|
||||
#h(7.3em) โดย Git นั้นจะทำการโคลนโปรเจกต์ไปที่โฟลเดอร์ `liteauth-firmware32`
|
||||
เนื่องจากเป็นชื่อของ Git repository หรือหากไม่ต้องการใช้ Git กรุณาไปที่
|
||||
https://gitskette.dailitation.xyz/linesofcodes/liteauth-firmware32 และทำการคลิกปุ่ม
|
||||
_Code_ แล้วกด _Download ZIP_ หรือ _Download TAR.GZ_ แล้วทำการแตกไฟล์ได้ตามปกติ
|
||||
จากนั้นจึงไปที่โฟลเดอร์ของคุณในเทอร์มินัลโดยใช้คำสั่ง `cd`
|
||||
|
||||
==== คำสั่ง PlatformIO เบื้องต้น
|
||||
|
||||
#[
|
||||
#set enum(indent: 7.3em)
|
||||
1. `pio run --list-targets` เพื่อดูรายการเป้าหมายคำสั่งรัน
|
||||
2. `pio run upload` เพื่อรันเป้าหมายอัพโหลด
|
||||
ซึ่งนี่คือคำสั่งที่คุณควรจะใช้ในการเขียนเฟิร์มแวร์ลงบนบอร์ด
|
||||
3. `pio device monitor` เพื่อเปิด Serial Monitor
|
||||
]
|
||||
|
||||
#h(7.3em) และโปรดใช้คำสั่งประเภท `pio run` ในโฟลเดอร์ของโปรเจกต์
|
||||
|
||||
#include "BuildApp.typ"
|
||||
|
||||
== การทดสอบ
|
||||
|
||||
#set enum(indent: 1.7em)
|
||||
1. เข้าแอพลิเคชัน liteauthconfig
|
||||
2. ทำการเชื่อมต่อไวไฟที่ต้องการให้อุปกรณ์เชื่อมต่อ (ต้องไม่ใช่ไวไฟ 2.4 GHz)
|
||||
3. กดปุ่มบวก
|
||||
4. กดตั้งค่าอุปกรณ์ใหม่ (Setup new device)
|
||||
5. ตั้งชื่ออุปกรณ์และใส่รหัสผ่านเครือข่าย
|
||||
6. กดปุ่มติ๊กถูกเพื่อเริ่มการตั้งค่าอุปกรณ์
|
||||
7. เข้าสู่โหมดลงทะเบียนอุปกรณ์ NFC
|
||||
8. ทำการแตะอุปกรณ์ NFC (เช่นโทรศัพท์ที่รองรับหรือแท็ก NFC)
|
||||
9. ออกจากโหมดลงทะเบียน
|
||||
10. ทำการแตะอุปกรณ์ NFC ที่ลงทะเบียน
|
||||
11. รอสังเกตุรายการกิจกรรม (Activity Logs)
|
||||
|
||||
== การวิเคราะห์ข้อมูล
|
||||
|
||||
#h(1.7em) วิเคราะห์จากตารางการทดลองตามความเร็วในการทำงานจริงของเครื่องยืนยันตัวตนด้วย NFC
|
||||
@@ -0,0 +1,74 @@
|
||||
#import "@preview/fletcher:0.5.8" as fletcher: diagram, edge, node
|
||||
#import fletcher.shapes: circle, diamond, pill
|
||||
|
||||
#diagram(
|
||||
node-stroke: 1pt,
|
||||
spacing: 2em,
|
||||
node([เริ่มต้น], shape: pill),
|
||||
edge("-|>"),
|
||||
node((1, 0), [ตั้งค่า LittleFS]),
|
||||
edge("-|>"),
|
||||
|
||||
node((1, 2), [มี Wi-Fi บันทึก\ ไว้อยู่หรือไม่], shape: diamond),
|
||||
edge("l", "-|>", [ไม่มี]),
|
||||
edge((1, 2), (1, 3), "-|>", [มี]),
|
||||
|
||||
node((0, 2), [รอรับรายละเอียดเครือข่าย\ (ESP-Touch)]),
|
||||
edge("d,r", "-|>"),
|
||||
node((1, 3), [เชื่อมต่อเครือข่าย]),
|
||||
edge("-|>"),
|
||||
|
||||
node((0, 3.5), [ตั้งค่าเซิร์ฟเวอร์ HTTPS]),
|
||||
edge("-|>"),
|
||||
|
||||
node((0, 5), [มีอุปกรณ์ควบคุม\ หลักแล้วหรือไม่], shape: diamond),
|
||||
edge("-|>", [ไม่มี]),
|
||||
edge("d", "-|>", [มี]),
|
||||
|
||||
node((1, 4), [สร้างโทเค็นสำหรับการยืนยัน\ อุปกรณ์ควบคุมหลัก]),
|
||||
edge("-|>"),
|
||||
|
||||
node((1, 5), [รออุปกรณ์ควบคุมหลัก\ ติดต่อกับอุปกรณ์]),
|
||||
edge("-|>"),
|
||||
|
||||
node((0, 6), shape: circle, radius: 1em),
|
||||
edge("-|>"),
|
||||
|
||||
node((0, 7), [มีการแตะเซนเซอร์\ NFC ขาเข้าหรือไม่], shape: diamond),
|
||||
edge("-|>", [ไม่มี]),
|
||||
|
||||
node((0, 9), [มีคนผ่านเซนเซอร์ PIR\ โดยไม่ได้รับอนุญาตหรือไม่], shape: diamond),
|
||||
edge((0, 9), (0, 10), [ไม่มี]),
|
||||
edge((0, 7), (1, 6), "-|>", [มี]),
|
||||
|
||||
node((1, 6), [อยู่ในโหมดลงทะเบียน\ หรือไม่], shape: diamond),
|
||||
edge("-|>", [ใช่]),
|
||||
edge((1, 6), (2, 7), [ไม่]),
|
||||
|
||||
node((1, 7), [นำ ID อุปกรณ์เข้า\ สู่รายการทะเบียน]),
|
||||
edge((1, 7), (0.6, 7), (0, 9), "-|>"),
|
||||
|
||||
node((2, 7), [ID ของอุปกรณ์อยู่\ ในทะเบียนหรือไม่], shape: diamond),
|
||||
edge("-|>", [อยู่]),
|
||||
edge((2, 7), (1, 8), "-|>", [ไม่อยู่], label-sep: -5pt),
|
||||
|
||||
node((2, 8), [ส่งเสียงคอนเฟิร์ม]),
|
||||
edge((2, 8), (2, 8.5), (0.4, 8.5), (0, 9), "-|>"),
|
||||
|
||||
node((1, 8), [ส่งเสียงแสดงความผิดพลาด]),
|
||||
edge((1, 8), (0.5, 8), (0, 9), "-|>"),
|
||||
|
||||
node((1, 9), [แจ้งเตือนทางเสียง\ และแอปพลิเคชัน]),
|
||||
edge((1, 9), (0, 10), "-|>"),
|
||||
edge((0, 10), (1, 10), "-|>", [มี]),
|
||||
|
||||
node((0, 10), [มีคำขอ HTTPS\ ใหม่หรือไม่], shape: diamond),
|
||||
edge((0, 10), (-2, 10), "-|>", [ไม่มี], label-pos: 10%),
|
||||
edge((0, 9), (1, 9), "-|>", [มี], label-anchor: "center", label-sep: -8pt),
|
||||
|
||||
node((1, 10), [ประมวลผลคำขอ HTTPS]),
|
||||
edge((1, 10), (1, 11), (-2, 11), (-2, 10), "-|>"),
|
||||
|
||||
node((-2, 10), shape: circle, radius: 1em),
|
||||
edge((-2, 10), (-2, 6), (0, 6), "-|>"),
|
||||
)
|
||||
@@ -0,0 +1,25 @@
|
||||
#import "@preview/fletcher:0.5.8" as fletcher: diagram, edge, node
|
||||
#import fletcher.shapes: circle, diamond, pill
|
||||
|
||||
#diagram(
|
||||
node-stroke: 1pt,
|
||||
spacing: 2em,
|
||||
node((0, 0), [เริ่มต้น], shape: pill),
|
||||
edge("-|>"),
|
||||
node((0, 1), shape: circle, radius: 1em),
|
||||
edge("-|>"),
|
||||
node((0, 2), [ศึกษาข้อมูลและทฤษฏีที่เกี่ยวข้อง], width: 2.5in),
|
||||
edge("-|>"),
|
||||
node((0, 3), [ออกแบบและวางแผนการดําเนินงาน], width: 2.5in),
|
||||
edge("-|>"),
|
||||
node((0, 4), [เครื่องยืนยันตัวตนด้วย NFC], width: 2.5in),
|
||||
edge("-|>"),
|
||||
node((0, 5), [ทดสอบประสิทธิภาพ], shape: diamond),
|
||||
edge("r,u,u,u,u,l", "-|>", [ไม่ผ่าน]),
|
||||
edge("-|>", [ผ่าน]),
|
||||
node((0, 6), [จัดทำเอกสาร], width: 2.5in),
|
||||
edge("-|>"),
|
||||
node((0, 7), [นำเสนอ], width: 2.5in),
|
||||
edge("-|>"),
|
||||
node((0, 8), [สิ้นสุด], shape: pill),
|
||||
)
|
||||
|
After Width: | Height: | Size: 3.6 MiB |
|
After Width: | Height: | Size: 2.8 MiB |
|
After Width: | Height: | Size: 839 KiB |
|
After Width: | Height: | Size: 21 KiB |
@@ -5,3 +5,93 @@
|
||||
#heading([#linebreak()ผลการทดสอบ])
|
||||
#set heading(numbering: "1.1")
|
||||
|
||||
#i ผลการทำโครงงานเครื่องยืนยันตัวตนด้วย NFC สามารถตรวจสอบอุปกรณ์ NFC
|
||||
ได้ตามวัตถุประสงค์ที่ตั้งไว้ในข้างต้น และสามารถใช้เป็นต้นแบบในการพัฒนาได้อีกต่อไป
|
||||
โดยการทดสอบจะทำการตรวจสอบค่าความหน่วง (latency)
|
||||
ของการติดต่อสื่อสารระหว่างอุปกรณ์ควบคุมและเครื่องยืนยันตัวตนเป็นหลัก
|
||||
โดยสิ่งที่เหมือนกันในทุกการทดลองคือแอพลิเคชันไคลเอนต์จะทำการขอข้อมูลใหม่ทุก 15
|
||||
วินาทีโดยไม่รอเวลาคำขอเก่าสำเร็จ
|
||||
|
||||
#i การทดสอบจะใช้อุปกรณ์ไคลเอนต์สองประเภทด้วยกัน ได้แก่ คอมพิวเตอร์และโทรศัพท์มือถือ
|
||||
โดยรายละเอียดทางเทคนิคของอุปกรณ์ไคลเอนต์ที่ใช้มีดังนี้
|
||||
|
||||
#set enum(indent: 3em)
|
||||
1. คอมพิวเตอร์ที่ใช้คือโน๊ตบุ๊ค MSI Thin 15 B12UCX
|
||||
#listy(
|
||||
numbering: thai-numbering,
|
||||
indent: 4.5em,
|
||||
[หน่วยประมวลผล Intel#sym.trademark.registered Core#sym.trademark i5-12450H],
|
||||
[ตัวควบคุมเครือข่ายไร้สาย Intel#sym.trademark.registered Wi-Fi 6E AX211],
|
||||
[ระบบปฏิบัติการ Arch Linux, Linux Kernel 6.18.9-arch1-2, Avahi 1:0.9rc3-1,
|
||||
`nss-mdns` 0.15.1-2],
|
||||
[มีการปรับแต่ง `nss-mdns` โดยการแก้ไขไฟล์ `/etc/nsswitch.conf` ในบรรทัด `hosts`
|
||||
เป็นดังนี้ (โดยไม่รวมการเว้นบรรทัดใหม่)
|
||||
#figure(
|
||||
```
|
||||
hosts: mymachines mdns4_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] files myhostname dns
|
||||
```,
|
||||
kind: image,
|
||||
caption: [บรรทัดที่มีการแก้ไขของไฟล์ `/etc/nsswitch.conf`],
|
||||
)
|
||||
#v(4em)
|
||||
],
|
||||
)
|
||||
2. โทรศัพท์มือถือที่ใช้คือ CMF by Nothing Phone 2 Pro
|
||||
#listy(
|
||||
numbering: thai-numbering,
|
||||
indent: 4.5em,
|
||||
[หน่วยประมวลผล MediaTek Dimensity 7300 Pro 5G],
|
||||
[Android 16 (Kernel 6.1.134, 14 พฤษภาคม 2025), Nothing OS 4.0, Build
|
||||
Galaga-B4.0-260108-1654],
|
||||
)
|
||||
|
||||
#i และรายละเอียดทางเทคนิคของเซิร์ฟเวอร์ (ESP32) มีดังนี้:
|
||||
|
||||
1. บอร์ด 30-pin ESP-WROOM-32 (NodeMCU)
|
||||
2. หน่วยประมวลผล Xtensa LX6 (240 MHz)
|
||||
3. หน่วยประมวลผลร่วม (Coprocessor) FSM (20 MHz)
|
||||
4. Wi-Fi 802.11 b/g/n/e/i
|
||||
#listy(
|
||||
numbering: thai-numbering,
|
||||
indent: 4.5em,
|
||||
[รองรับเครือข่าย Wi-Fi 2 (802.11b), Wi-Fi 3 (802.11g), และ Wi-Fi 4 (802.11n)],
|
||||
[รองรับ 802.11n ในคลื่นความถี่ 2.4 GHz และความเร็วสูงสุด 150 Mbps],
|
||||
[รองรับมาตรฐานปรับปรุงคุณภาพบริการเครือข่ายไร้สาย (802.11e)],
|
||||
[รองรับมาตรฐานความปลอดภัย 802.11i (ซึ่งเป็นส่วนหนึ่งของ WPA2)],
|
||||
)
|
||||
5. SRAM 520 KiB
|
||||
6. ROM 448 KiB
|
||||
|
||||
== ระยะเวลาในการเดินทางของข้อมูลทั้งสิ้น
|
||||
|
||||
#h(1.7em)
|
||||
โดยการทดสอบนี้จะทำการเปรียบเทียบและหาระยะเวลาที่ใช้ในการเดินทางของข้อมูลตั้งแต่เซนเซอร์ถูกใช้จนถึงเวลาไคลเอนต์ได้รับข้อมูลบนอุปกรณ์ไคลเอนต์ทั้งสองประเภท
|
||||
|
||||
#figure(
|
||||
table(
|
||||
columns: (2em, 2fr, 2fr, 1fr),
|
||||
[ที่], [เวลาที่ตรวจจับ], [เวลาที่ไคลเอนต์ได้รับข้อมูล], [ความต่าง (ms)],
|
||||
[1], [2026-02-26T05:52:56.380Z], [2026-02-26T05:53:03.239Z], [6859ms],
|
||||
[2], [2026-02-26T07:07:32.241Z], [2026-02-26T07:07:44.924Z], [12683ms],
|
||||
[3], [2026-02-26T07:09:21.382Z], [2026-02-26T07:09:31.166Z], [9784ms],
|
||||
),
|
||||
caption: [ระยะเวลาในการเดินทางของข้อมูลทั้งสิ้นบนคอมพิวเตอร์],
|
||||
)
|
||||
|
||||
#figure(
|
||||
table(
|
||||
columns: (2em, 2fr, 2fr, 1fr),
|
||||
[ที่], [เวลาที่ตรวจจับ], [เวลาที่ไคลเอนต์ได้รับข้อมูล], [ความต่าง (ms)],
|
||||
),
|
||||
caption: [ระยะเวลาในการเดินทางของข้อมูลทั้งสิ้นบนโทรศัพท์มือถือ],
|
||||
)
|
||||
|
||||
== ระยะเวลาในการส่งคำขอ
|
||||
|
||||
#figure(
|
||||
table(
|
||||
columns: (1fr, 2fr, 2fr),
|
||||
[ที่], [คอมพิวเตอร์], [โทรศัพท์มือถือ],
|
||||
),
|
||||
caption: [เปรียบเทียบระยะเวลาในการส่งคำขอ],
|
||||
)
|
||||
|
||||
@@ -6,8 +6,33 @@
|
||||
#counter(heading).update((5, 0))
|
||||
#set heading(numbering: "1.1")
|
||||
|
||||
#i จากการทำโครงงานเรื่อง เครื่องยืนยันตัวตนด้วย NFC โดยมีวัตถุประสงค์เผื่อ
|
||||
|
||||
การจัดทำโครงงานครั้งนี้ ผู้จัดทำได้ผลสรุปดังนี้
|
||||
|
||||
== สรุปผลโครงงาน
|
||||
|
||||
#h(1.7em) เครื่องยืนยันตัวตนด้วย NFC สามารถทำงานได้ตามวัตถุประสงค์ที่ตั้งไว้ โดยเมื่อมีการแตะบัตรหรือสมาร์ตโฟนที่รองรับ NFC เข้ากับตัวอ่าน ระบบจะทำการตรวจสอบข้อมูลกับฐานข้อมูลที่บันทึกไว้ หากข้อมูลถูกต้อง ระบบจะสั่งปลดล็อกและอนุญาตให้เข้าใช้งานได้ แต่หากข้อมูลไม่ถูกต้อง ระบบจะไม่อนุญาตและอาจมีการแจ้งเตือน
|
||||
|
||||
#h(1.7em) 5.1.1 โมดูล NFC สามารถอ่านข้อมูลจากบัตรได้อย่างถูกต้องในระยะใกล้
|
||||
|
||||
#h(1.7em) 5.1.2 บอร์ดควบคุมสามารถประมวลผลข้อมูลและสั่งงานอุปกรณ์ได้ตามโปรแกรมที่กำหนด
|
||||
|
||||
#h(1.7em) 5.1.3 ระบบสามารถลดการใช้กุญแจแบบเดิม และเพิ่มความสะดวกให้กับผู้ใช้งาน
|
||||
|
||||
== อภิปรายผล
|
||||
|
||||
#h(1.7em) จากการทดลองใช้งานจริง พบว่าเครื่องสามารถอ่านบัตรได้รวดเร็ว ใช้เวลาเพียงไม่กี่วินาทีในการตรวจสอบสิทธิ์การเข้าใช้งาน ระบบมีความแม่นยำสูงเมื่ออยู่ในระยะที่เหมาะสม อย่างไรก็ตาม หากวางบัตรห่างจากตัวอ่านมากเกินไป ระบบจะไม่สามารถอ่านข้อมูลได้
|
||||
|
||||
การใช้งาน NFC ช่วยเพิ่มความปลอดภัย เนื่องจากต้องมีบัตรหรืออุปกรณ์ที่ลงทะเบียนไว้เท่านั้นจึงจะสามารถเข้าใช้งานได้ ทำให้ลดความเสี่ยงจากบุคคลภายนอกได้อย่างมีประสิทธิภาพ
|
||||
|
||||
== ข้อเสนอแนะ
|
||||
|
||||
#h(1.7em) 5.3.1 ควรพัฒนาให้สามารถบันทึกข้อมูลการเข้า–ออกเพื่อตรวจสอบย้อนหลังได้
|
||||
|
||||
#h(1.7em) 5.3.2 ควรเพิ่มระบบแจ้งเตือนผ่านแอปพลิเคชันหรือไลน์เมื่อมีการเข้าใช้งาน
|
||||
|
||||
#h(1.7em) 5.3.3 ควรพัฒนาระบบให้รองรับผู้ใช้งานจำนวนมากขึ้น
|
||||
|
||||
#h(1.7em) 5.3.4
|
||||
ควรออกแบบกล่องอุปกรณ์ให้มีความแข็งแรงและสวยงามมากขึ้น
|
||||
@@ -3,7 +3,7 @@
|
||||
set page(
|
||||
paper: "a4",
|
||||
margin: (
|
||||
top: 1.5in,
|
||||
top: 4cm,
|
||||
left: 1.5in,
|
||||
right: 1in,
|
||||
bottom: 1in,
|
||||
@@ -29,15 +29,15 @@
|
||||
"assets/nktc.jpg",
|
||||
width: 4cm,
|
||||
alt: "วิทยาลัยเทคนิคหนองคาย",
|
||||
)
|
||||
)\
|
||||
|
||||
เครื่องยืนยันตัวตนด้วย NFC
|
||||
|
||||
#v(8em)
|
||||
#v(1fr)
|
||||
|
||||
#grid(
|
||||
columns: 2,
|
||||
align: (right, left),
|
||||
align: left,
|
||||
column-gutter: 1em,
|
||||
row-gutter: 0.75em,
|
||||
"ประภากร", "ศรีวรสาร",
|
||||
@@ -45,7 +45,7 @@
|
||||
"ศตคุณ", "อุตมะ",
|
||||
)
|
||||
|
||||
#v(10em)
|
||||
#v(1fr)
|
||||
|
||||
โครงงานนี้เป็นส่วนหนึ่งของ วิชาโครงงานรหัสวิชา 21909-2023 \
|
||||
ตามหลักสูตรประกาศนียบัตรวิชาชีพ พุทธศักราช 2567 \
|
||||
@@ -0,0 +1,940 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!-- Dracula Theme v1.4.3
|
||||
#
|
||||
# https://github.com/dracula/sublime
|
||||
#
|
||||
# Copyright 2013-present, All rights reserved
|
||||
#
|
||||
# Code licensed under the MIT license
|
||||
#
|
||||
# @author Zeno Rocha <hi@zenorocha.com>
|
||||
-->
|
||||
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Dracula</string>
|
||||
<key>settings</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string>#282a36</string>
|
||||
<key>caret</key>
|
||||
<string>#f8f8f0</string>
|
||||
<key>block_caret</key>
|
||||
<string>#999a9e</string>
|
||||
<key>foreground</key>
|
||||
<string>#f8f8f2</string>
|
||||
<key>invisibles</key>
|
||||
<string>#3B3A32</string>
|
||||
<key>lineHighlight</key>
|
||||
<string>#44475a</string>
|
||||
<key>selection</key>
|
||||
<string>#44475a</string>
|
||||
<key>findHighlight</key>
|
||||
<string>#effb7b</string>
|
||||
<key>findHighlightForeground</key>
|
||||
<string>#000000</string>
|
||||
<key>selectionBorder</key>
|
||||
<string>#222218</string>
|
||||
<key>activeGuide</key>
|
||||
<string>#9D550FB0</string>
|
||||
<key>bracketsForeground</key>
|
||||
<string>#F8F8F2A5</string>
|
||||
<key>bracketsOptions</key>
|
||||
<string>underline</string>
|
||||
<key>bracketContentsForeground</key>
|
||||
<string>#F8F8F2A5</string>
|
||||
<key>bracketContentsOptions</key>
|
||||
<string>underline</string>
|
||||
<key>tagsOptions</key>
|
||||
<string>stippled_underline</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Comment</string>
|
||||
<key>scope</key>
|
||||
<string>comment</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#6272a4</string>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>String</string>
|
||||
<key>scope</key>
|
||||
<string>string</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#f1fa8c</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Number</string>
|
||||
<key>scope</key>
|
||||
<string>constant.numeric</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#bd93f9</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Built-in constant</string>
|
||||
<key>scope</key>
|
||||
<string>constant.language</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#bd93f9</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>User-defined constant</string>
|
||||
<key>scope</key>
|
||||
<string>constant.character, constant.other</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#bd93f9</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Variable</string>
|
||||
<key>scope</key>
|
||||
<string>variable</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Ruby's @variable</string>
|
||||
<key>scope</key>
|
||||
<string>variable.other.readwrite.instance</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#ffb86c</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>String interpolation</string>
|
||||
<key>scope</key>
|
||||
<string>constant.character.escaped, constant.character.escape, string source, string source.ruby</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#ff79c6</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Ruby Regexp</string>
|
||||
<key>scope</key>
|
||||
<string>source.ruby string.regexp.classic.ruby,source.ruby string.regexp.mod-r.ruby</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#ff5555</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Keyword</string>
|
||||
<key>scope</key>
|
||||
<string>keyword</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#ff79c6</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Storage</string>
|
||||
<key>scope</key>
|
||||
<string>storage</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#ff79c6</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Storage type</string>
|
||||
<key>scope</key>
|
||||
<string>storage.type</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
<key>foreground</key>
|
||||
<string>#8be9fd</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Storage Type Namespace</string>
|
||||
<key>scope</key>
|
||||
<string>storage.type.namespace</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
<key>foreground</key>
|
||||
<string>#8be9fd</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Storage Type Class</string>
|
||||
<key>scope</key>
|
||||
<string>storage.type.class</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
<key>foreground</key>
|
||||
<string>#ff79c6</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Class name</string>
|
||||
<key>scope</key>
|
||||
<string>entity.name.class</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>underline</string>
|
||||
<key>foreground</key>
|
||||
<string>#8be9fd</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Meta Path</string>
|
||||
<key>scope</key>
|
||||
<string>meta.path</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>underline</string>
|
||||
<key>foreground</key>
|
||||
<string>#66d9ef</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Inherited class</string>
|
||||
<key>scope</key>
|
||||
<string>entity.other.inherited-class</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic underline</string>
|
||||
<key>foreground</key>
|
||||
<string>#8be9fd</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Function name</string>
|
||||
<key>scope</key>
|
||||
<string>entity.name.function</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#50fa7b</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Function argument</string>
|
||||
<key>scope</key>
|
||||
<string>variable.parameter</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
<key>foreground</key>
|
||||
<string>#ffb86c</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Tag name</string>
|
||||
<key>scope</key>
|
||||
<string>entity.name.tag</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#ff79c6</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Tag attribute</string>
|
||||
<key>scope</key>
|
||||
<string>entity.other.attribute-name</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#50fa7b</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Library function</string>
|
||||
<key>scope</key>
|
||||
<string>support.function</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#8be9fd</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Library constant</string>
|
||||
<key>scope</key>
|
||||
<string>support.constant</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#6be5fd</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Library class/type</string>
|
||||
<key>scope</key>
|
||||
<string>support.type, support.class</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
<key>foreground</key>
|
||||
<string>#66d9ef</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Library variable</string>
|
||||
<key>scope</key>
|
||||
<string>support.other.variable</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Support Other Namespace</string>
|
||||
<key>scope</key>
|
||||
<string>support.other.namespace</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
<key>foreground</key>
|
||||
<string>#66d9ef</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Invalid</string>
|
||||
<key>scope</key>
|
||||
<string>invalid</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string>#ff79c6</string>
|
||||
<key>fontStyle</key>
|
||||
<string></string>
|
||||
<key>foreground</key>
|
||||
<string>#F8F8F0</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Invalid deprecated</string>
|
||||
<key>scope</key>
|
||||
<string>invalid.deprecated</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>background</key>
|
||||
<string>#bd93f9</string>
|
||||
<key>foreground</key>
|
||||
<string>#F8F8F0</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>JSON String</string>
|
||||
<key>scope</key>
|
||||
<string>meta.structure.dictionary.json string.quoted.double.json</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#CFCFC2</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>diff.header</string>
|
||||
<key>scope</key>
|
||||
<string>meta.diff, meta.diff.header</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#6272a4</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>diff.deleted</string>
|
||||
<key>scope</key>
|
||||
<string>markup.deleted</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#ff79c6</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>diff.inserted</string>
|
||||
<key>scope</key>
|
||||
<string>markup.inserted</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#50fa7b</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>diff.changed</string>
|
||||
<key>scope</key>
|
||||
<string>markup.changed</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#E6DB74</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>scope</key>
|
||||
<string>constant.numeric.line-number.find-in-files - match</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#bd93f9</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>scope</key>
|
||||
<string>entity.name.filename</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#E6DB74</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>scope</key>
|
||||
<string>message.error</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#F83333</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>JSON Punctuation</string>
|
||||
<key>scope</key>
|
||||
<string>punctuation.definition.string.begin.json - meta.structure.dictionary.value.json, punctuation.definition.string.end.json - meta.structure.dictionary.value.json</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#EEEEEE</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>JSON Structure</string>
|
||||
<key>scope</key>
|
||||
<string>meta.structure.dictionary.json string.quoted.double.json</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#8be9fd</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>JSON String</string>
|
||||
<key>scope</key>
|
||||
<string>meta.structure.dictionary.value.json string.quoted.double.json</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#f1fa8c</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>JSON: 6 deep</string>
|
||||
<key>scope</key>
|
||||
<string>meta meta meta meta meta meta meta.structure.dictionary.value string</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#50fa7b</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>JSON: 5 deep</string>
|
||||
<key>scope</key>
|
||||
<string>meta meta meta meta meta meta.structure.dictionary.value string</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#ffb86c</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>JSON: 4 deep</string>
|
||||
<key>scope</key>
|
||||
<string>meta meta meta meta meta.structure.dictionary.value string</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#ff79c6</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>JSON: 3 deep</string>
|
||||
<key>scope</key>
|
||||
<string>meta meta meta meta.structure.dictionary.value string</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#bd93f9</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>JSON: 2 deep</string>
|
||||
<key>scope</key>
|
||||
<string>meta meta meta.structure.dictionary.value string</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#50fa7b</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>JSON: 1 deep</string>
|
||||
<key>scope</key>
|
||||
<string>meta meta.structure.dictionary.value string</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#ffb86c</string>
|
||||
</dict>
|
||||
</dict>
|
||||
|
||||
<!-- Markdown Tweaks -->
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markup: strike</string>
|
||||
<key>scope</key>
|
||||
<string>markup.strike</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
<key>foreground</key>
|
||||
<string>#FFB86C</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markup: bold</string>
|
||||
<key>scope</key>
|
||||
<string>markup.bold</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>bold</string>
|
||||
<key>foreground</key>
|
||||
<string>#FFB86C</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markup: italic</string>
|
||||
<key>scope</key>
|
||||
<string>markup.italic</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
<key>foreground</key>
|
||||
<string>#FFB86C</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markdown: heading</string>
|
||||
<key>scope</key>
|
||||
<string>markup.heading</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#8BE9FD</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markdown: List Items Punctuation</string>
|
||||
<key>scope</key>
|
||||
<string>punctuation.definition.list_item.markdown</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#FF79C6</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markdown: Blockquote</string>
|
||||
<key>scope</key>
|
||||
<string>markup.quote</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
<key>foreground</key>
|
||||
<string>#6272A4</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markdown: Blockquote Punctuation</string>
|
||||
<key>scope</key>
|
||||
<string>punctuation.definition.blockquote.markdown</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
<key>background</key>
|
||||
<string>#6272A4</string>
|
||||
<key>foreground</key>
|
||||
<string>#6272A4</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markdown: Separator</string>
|
||||
<key>scope</key>
|
||||
<string>meta.separator</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#6272A4</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markup: raw inline</string>
|
||||
<key>scope</key>
|
||||
<string>text.html.markdown markup.raw.inline</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#50FA7B</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markup: underline</string>
|
||||
<key>scope</key>
|
||||
<string>markup.underline</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>underline</string>
|
||||
<key>foreground</key>
|
||||
<string>#BD93F9</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markup: Raw block</string>
|
||||
<key>scope</key>
|
||||
<string>markup.raw.block</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#CFCFC2</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markdown: Raw Block fenced source</string>
|
||||
<key>scope</key>
|
||||
<string>markup.raw.block.fenced.markdown source</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#F8F8F2</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markdown: Fenced Bode Block</string>
|
||||
<key>scope</key>
|
||||
<string>punctuation.definition.fenced.markdown, variable.language.fenced.markdown</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
<key>foreground</key>
|
||||
<string>#6272A4</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Markdown: Fenced Language</string>
|
||||
<key>scope</key>
|
||||
<string>variable.language.fenced.markdown</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>fontStyle</key>
|
||||
<string>italic</string>
|
||||
<key>foreground</key>
|
||||
<string>#6272A4</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Punctuation Accessor</string>
|
||||
<key>scope</key>
|
||||
<string>punctuation.accessor</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#FF79C6</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Meta Function Return Type</string>
|
||||
<key>scope</key>
|
||||
<string>meta.function.return-type</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#FF79C6</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Punctuation Section Block Begin</string>
|
||||
<key>scope</key>
|
||||
<string>punctuation.section.block.begin</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#ffffff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Punctuation Section Block End</string>
|
||||
<key>scope</key>
|
||||
<string>punctuation.section.block.end</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#ffffff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Punctuation Section Embedded Begin</string>
|
||||
<key>scope</key>
|
||||
<string>punctuation.section.embedded.begin</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#ff79c6</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Punctuation Section Embedded End</string>
|
||||
<key>scope</key>
|
||||
<string>punctuation.section.embedded.end</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#ff79c6</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Punctuation Separator Namespace</string>
|
||||
<key>scope</key>
|
||||
<string>punctuation.separator.namespace</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#ff79c6</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Variable Function</string>
|
||||
<key>scope</key>
|
||||
<string>variable.function</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#50fa7b</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Variable Other</string>
|
||||
<key>scope</key>
|
||||
<string>variable.other</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#ffffff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Variable Language</string>
|
||||
<key>scope</key>
|
||||
<string>variable.language</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#bd93f9</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Entity Name Module Ruby</string>
|
||||
<key>scope</key>
|
||||
<string>entity.name.module.ruby</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#8be9fd</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Entity Name Constant Ruby</string>
|
||||
<key>scope</key>
|
||||
<string>entity.name.constant.ruby</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#bd93f9</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Support Function Builtin Ruby</string>
|
||||
<key>scope</key>
|
||||
<string>support.function.builtin.ruby</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#ffffff</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Storage Type Namespace CS</string>
|
||||
<key>scope</key>
|
||||
<string>storage.type.namespace.cs</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#ff79c6</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>Entity Name Namespace CS</string>
|
||||
<key>scope</key>
|
||||
<string>entity.name.namespace.cs</string>
|
||||
<key>settings</key>
|
||||
<dict>
|
||||
<key>foreground</key>
|
||||
<string>#8be9fd</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
<key>uuid</key>
|
||||
<string>83091B89-765E-4F0D-9275-0EC6CB084126</string>
|
||||
<key>colorSpaceName</key>
|
||||
<string>sRGB</string>
|
||||
<key>semanticClass</key>
|
||||
<string>theme.dracula</string>
|
||||
<key>author</key>
|
||||
<string>Zeno Rocha</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1,4 +1,4 @@
|
||||
#let thai-numbering(n) = {
|
||||
#let page-numbering(n) = {
|
||||
let chars = ("ก", "ข", "ค", "ง", "จ", "ฉ", "ช")
|
||||
if n <= chars.len() {
|
||||
chars.at(n - 1)
|
||||
@@ -7,6 +7,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
#let thai-numbering(n) = {
|
||||
let chars = ("ก", "ข", "ค", "ง", "จ", "ฉ", "ช", "ซ", "ฌ", "ญ")
|
||||
if n <= chars.len() {
|
||||
chars.at(n - 1)
|
||||
} else {
|
||||
str(n - chars.len()) // fallback to numbers if exceeds available characters
|
||||
}
|
||||
[)]
|
||||
}
|
||||
|
||||
#let chapter-page(doc) = {
|
||||
set page(
|
||||
paper: "a4",
|
||||
@@ -16,15 +26,156 @@
|
||||
right: 1in,
|
||||
bottom: 1in,
|
||||
),
|
||||
header: context [
|
||||
#h(1fr)
|
||||
#counter(page).display(thai-numbering)
|
||||
],
|
||||
header: none,
|
||||
)
|
||||
doc
|
||||
}
|
||||
|
||||
#let page-theme(doc) = {
|
||||
/// Sane indentation
|
||||
#let i = h(3em)
|
||||
|
||||
/// Insane shit forced upon by my teacher
|
||||
/// For indenting in 3rd level subheadings
|
||||
#let iii = h(4.1em)
|
||||
/// For indenting in 4th level subheadings
|
||||
#let iiii = h(7.55em)
|
||||
#let iiiii = h(13em)
|
||||
#let iiiiii = h(16.85em)
|
||||
|
||||
#let listy(
|
||||
numbering: "1)",
|
||||
indent: 1em,
|
||||
hanging-indent: 0em,
|
||||
body-spacing: .3em,
|
||||
..items,
|
||||
) = context {
|
||||
let nums = range(1, items.pos().len() + 1)
|
||||
let fnums = nums.map(std.numbering.with(numbering))
|
||||
let numwidth = calc.max(..fnums.map(it => measure(it).width))
|
||||
for (num, item) in fnums.zip(items.pos()) {
|
||||
block(inset: (left: hanging-indent), {
|
||||
h(indent - hanging-indent)
|
||||
box(width: numwidth + body-spacing, stroke: none, num)
|
||||
item
|
||||
})
|
||||
v(1em, weak: true)
|
||||
}
|
||||
}
|
||||
|
||||
#let page-theme(doc, has-header: true) = {
|
||||
set page(
|
||||
paper: "a4",
|
||||
margin: (
|
||||
top: 1.5in,
|
||||
left: 1.5in,
|
||||
right: 1in,
|
||||
bottom: 1in,
|
||||
),
|
||||
header: if has-header {
|
||||
context [
|
||||
#h(1fr)
|
||||
#counter(page).display(page-numbering)
|
||||
]
|
||||
},
|
||||
)
|
||||
set text(
|
||||
lang: "th",
|
||||
font: "Laksaman",
|
||||
size: 10.5pt,
|
||||
)
|
||||
set par(
|
||||
justify: true,
|
||||
justification-limits: (
|
||||
tracking: (min: -1pt, max: 3pt),
|
||||
),
|
||||
leading: 1em,
|
||||
)
|
||||
set list(indent: 1em)
|
||||
show raw.where(block: false): set text(font: "Laksaman", size: 10.5pt)
|
||||
show raw.where(block: true): set block(
|
||||
fill: rgb("#282A36"),
|
||||
stroke: black + 2pt,
|
||||
inset: 1.5em,
|
||||
)
|
||||
show raw.where(block: true): set raw(theme: "Dracula.tmTheme")
|
||||
show raw.where(block: true): set text(
|
||||
fill: rgb("#F8F8F2"),
|
||||
font: "Cascadia Code",
|
||||
size: 10pt,
|
||||
)
|
||||
show heading: set text(size: 10.5pt, weight: "regular")
|
||||
show heading: set block(below: 1em)
|
||||
show heading.where(level: 1): set text(size: 12pt, weight: "bold")
|
||||
show heading.where(level: 1): set align(center)
|
||||
show heading.where(level: 1): set block(below: 2em)
|
||||
show heading.where(level: 2): set block(above: 2em)
|
||||
show heading.where(level: 2): set text(weight: "bold")
|
||||
show math.equation: set text(font: "Laksaman")
|
||||
show table.cell.where(y: 0): strong
|
||||
show figure.where(kind: "i-figured-table"): set align(start)
|
||||
show figure.where(kind: table): set figure.caption(position: top)
|
||||
show figure.where(kind: table): t => {
|
||||
show figure.caption: it => {
|
||||
it.supplement
|
||||
" "
|
||||
it.counter.display(it.numbering)
|
||||
" "
|
||||
it.body
|
||||
}
|
||||
it
|
||||
}
|
||||
show figure.where(kind: "i-figured-image"): i => {
|
||||
show figure.caption: it => {
|
||||
place(
|
||||
center,
|
||||
[
|
||||
#text(weight: "bold")[
|
||||
#it.supplement
|
||||
#it.counter.display(it.numbering)
|
||||
]
|
||||
#it.body
|
||||
],
|
||||
dy: 2em,
|
||||
)
|
||||
}
|
||||
show image: it => {
|
||||
block(stroke: black + 2pt, it)
|
||||
}
|
||||
i
|
||||
}
|
||||
set figure.caption(separator: " ")
|
||||
show figure.where(kind: image): set block(below: 2.5em)
|
||||
set enum(number-align: start + top)
|
||||
show enum.item: it => context {
|
||||
if (it.number == auto) {
|
||||
return it
|
||||
}
|
||||
|
||||
let spacing = enum.indent
|
||||
if spacing == auto {
|
||||
if enum.tight {
|
||||
spacing = par.leading
|
||||
} else {
|
||||
spacing = par.spacing
|
||||
}
|
||||
}
|
||||
(
|
||||
h(spacing)
|
||||
+ [#{ str(it.number) + ")" }]
|
||||
+ h(enum.body-indent)
|
||||
+ it.body
|
||||
+ linebreak()
|
||||
)
|
||||
}
|
||||
set ref(supplement: "หัวข้อ")
|
||||
doc
|
||||
}
|
||||
|
||||
#let fake-h1(body) = {
|
||||
align(center, text(body, weight: "bold", size: 12pt))
|
||||
}
|
||||
|
||||
#let sane-theme(doc) = {
|
||||
set page(
|
||||
paper: "a4",
|
||||
margin: (
|
||||
@@ -35,7 +186,7 @@
|
||||
),
|
||||
header: context [
|
||||
#h(1fr)
|
||||
#counter(page).display(thai-numbering)
|
||||
#counter(page).display(page-numbering)
|
||||
],
|
||||
)
|
||||
set text(
|
||||
@@ -51,12 +202,23 @@
|
||||
leading: 1em,
|
||||
)
|
||||
set list(indent: 1em)
|
||||
show raw: set text(font: "Cascadia Code")
|
||||
show heading: set text(size: 10.5pt)
|
||||
show heading: set block(below: 1em)
|
||||
show heading.where(level: 1): set text(size: 12pt)
|
||||
show heading.where(level: 1): set align(center)
|
||||
show raw: set text(font: "Cascadia Code", size: 10pt)
|
||||
show heading.where(level: 1): set text(size: 12pt, weight: "bold")
|
||||
show heading.where(level: 2): set text(weight: "bold")
|
||||
show math.equation: set text(font: "Laksaman")
|
||||
show table.cell.where(y: 0): strong
|
||||
show figure.caption: it => {
|
||||
text(weight: "bold")[
|
||||
#it.supplement
|
||||
#it.counter.display(it.numbering)
|
||||
#it.separator
|
||||
]
|
||||
it.body
|
||||
}
|
||||
set figure.caption(separator: "")
|
||||
set enum(number-align: start + top)
|
||||
set ref(supplement: "หัวข้อ")
|
||||
doc
|
||||
}
|
||||
@@ -64,7 +226,7 @@
|
||||
// Figure with attribution information
|
||||
#let afigure(
|
||||
body,
|
||||
attr: "",
|
||||
attr: none,
|
||||
..args,
|
||||
) = [
|
||||
#figure(body, ..args)
|
||||
@@ -75,6 +237,4 @@
|
||||
) <afig>
|
||||
]
|
||||
|
||||
#let i = h(3em)
|
||||
|
||||
#let jb = linebreak(justify: true)
|
||||
|
||||
@@ -11,22 +11,32 @@ wkNodeMcu:
|
||||
wkEsp32:
|
||||
type: Web
|
||||
title: ESP32
|
||||
date: 2025-11-2
|
||||
date: 2025-12-27
|
||||
language: en
|
||||
publisher: มูลนิธิวิกิมีเดีย (ภายใต้ CC BY-SA 4.0)
|
||||
url:
|
||||
date: 2025-12-8
|
||||
value: https://en.wikipedia.org/w/index.php?title=ESP32&oldid=1320113248
|
||||
date: 2025-12-28
|
||||
value: https://en.wikipedia.org/w/index.php?title=ESP32&oldid=1329754183
|
||||
|
||||
wkEspressif:
|
||||
type: Web
|
||||
title: Espressif Systems
|
||||
date: 2025-10-6
|
||||
date: 2025-11-28
|
||||
language: en
|
||||
publisher: มูลนิธิวิกิมีเดีย (ภายใต้ CC BY-SA 4.0)
|
||||
url:
|
||||
date: 2025-12-8
|
||||
value: https://en.wikipedia.org/w/index.php?title=Espressif_Systems&oldid=1315427960
|
||||
date: 2025-12-29
|
||||
value: https://en.wikipedia.org/w/index.php?title=Espressif_Systems&oldid=1324514195
|
||||
|
||||
wkMicrocontroller:
|
||||
type: Web
|
||||
title: Microcontroller
|
||||
date: 2025-12-21
|
||||
language: en
|
||||
publisher: มูลนิธิวิกิมีเดีย (ภายใต้ CC BY-SA 4.0)
|
||||
url:
|
||||
date: 2025-12-28
|
||||
value: https://en.wikipedia.org/w/index.php?title=Microcontroller&oldid=1328645390
|
||||
|
||||
wkFlutter:
|
||||
type: Web
|
||||
@@ -81,12 +91,12 @@ wkTls:
|
||||
wkC:
|
||||
type: Web
|
||||
title: C (programming language)
|
||||
date: 2025-11-26
|
||||
date: 2026-1-3
|
||||
language: en
|
||||
publisher: มูลนิธิวิกิมีเดีย (ภายใต้ CC BY-SA 4.0)
|
||||
url:
|
||||
date: 2025-11-30
|
||||
value: https://en.wikipedia.org/w/index.php?title=C_(programming_language)&oldid=1324211766
|
||||
date: 2026-1-5
|
||||
value: https://en.wikipedia.org/w/index.php?title=C_(programming_language)&oldid=1330924334
|
||||
|
||||
wkGcc:
|
||||
type: Web
|
||||
@@ -168,6 +178,36 @@ wkNFC:
|
||||
date: 2025-12-10
|
||||
value: https://en.wikipedia.org/w/index.php?title=Near-field_communication&oldid=1320616102
|
||||
|
||||
wkWiFi:
|
||||
type: Web
|
||||
title: Wi-Fi
|
||||
date: 2026-02-18
|
||||
language: en
|
||||
publisher: มูลนิธิวิกิมีเดีย (ภายใต้ CC BY-SA 4.0)
|
||||
url:
|
||||
date: 2026-02-19
|
||||
value: https://en.wikipedia.org/w/index.php?title=Wi-Fi&oldid=1338995964
|
||||
|
||||
wkIEEE80211i:
|
||||
type: Web
|
||||
date: 2025-03-22
|
||||
title: IEEE 802.11i-2004
|
||||
language: en
|
||||
publisher: มูลนิธิวิกิมีเดีย (ภายใต้ CC BY-SA 4.0)
|
||||
url:
|
||||
date: 2026-02-19
|
||||
value: https://en.wikipedia.org/w/index.php?title=IEEE_802.11i-2004&oldid=1281726294
|
||||
|
||||
wkIEEE80211e:
|
||||
type: Web
|
||||
date: 2025-08-26
|
||||
title: IEEE 802.11e-2005
|
||||
language: en
|
||||
publisher: มูลนิธิวิกิมีเดีย (ภายใต้ CC BY-SA 4.0)
|
||||
url:
|
||||
date: 2026-02-19
|
||||
value: https://en.wikipedia.org/w/index.php?title=IEEE_802.11e-2005&oldid=1307917729
|
||||
|
||||
androidJdkVersion:
|
||||
type: Web
|
||||
title: Java versions in Android builds
|
||||
@@ -240,6 +280,16 @@ flLinuxBuild:
|
||||
date: 2025-12-6
|
||||
value: https://docs.flutter.dev/platform-integration/linux/building
|
||||
|
||||
flArchOverview:
|
||||
type: Web
|
||||
title: Flutter architectural overview
|
||||
date: 2025-12-8
|
||||
language: en
|
||||
publisher: Flutter (ภายใต้ CC BY 3.0 และ BSD License)
|
||||
url:
|
||||
date: 2025-12-30
|
||||
value: https://docs.flutter.dev/resources/architectural-overview
|
||||
|
||||
archPkgs:
|
||||
type: Web
|
||||
title: Arch Linux - Package Search
|
||||
@@ -314,7 +364,11 @@ ansiC:
|
||||
language: en
|
||||
edition: ฉบับที่สอง (Second edition)
|
||||
date: 1988
|
||||
url: https://archive.org/details/the-ansi-c-programming-language-by-brian-w.-kernighan-dennis-m.-ritchie.org
|
||||
serial-number:
|
||||
isbn: 0131101633
|
||||
url:
|
||||
date: 2025-12-11
|
||||
value: https://archive.org/details/the-ansi-c-programming-language-by-brian-w.-kernighan-dennis-m.-ritchie.org
|
||||
|
||||
ghEsp32Partition:
|
||||
type: Web
|
||||
@@ -351,3 +405,10 @@ pioInsScript:
|
||||
date: 2025-12-15
|
||||
value: https://docs.platformio.org/en/latest/core/installation/methods/installer-script.html
|
||||
|
||||
esp32Datasheet:
|
||||
type: reference
|
||||
date: 2016-10-8
|
||||
title: ESP32 Datasheet
|
||||
url:
|
||||
date: 2026-02-19
|
||||
value: https://www.esp32.dk/esp32_datasheet_en.pdf
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# HTTP API
|
||||
|
||||
This folder documents the HTTP API. The contents of this is not included in the
|
||||
printed book version.
|
||||
@@ -0,0 +1,76 @@
|
||||
= HTTP API
|
||||
|
||||
== Authorization
|
||||
|
||||
The API uses the `Authorization` header with a 16 characters long bearer token.
|
||||
|
||||
An example of the header would be:
|
||||
|
||||
```
|
||||
Authorization: Bearer tC8UMiiyaLnVWaW2
|
||||
```
|
||||
|
||||
The token is generated from a set of characters:
|
||||
|
||||
```
|
||||
abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
|
||||
```
|
||||
|
||||
Which means you can also create a mock token by using the following code:
|
||||
|
||||
```py
|
||||
import string
|
||||
import random
|
||||
|
||||
s = string.ascii_letters + string.digits
|
||||
|
||||
for i in range(16):
|
||||
print(random.choice(s), end="")
|
||||
|
||||
print()
|
||||
```
|
||||
|
||||
== [GET] /api/status
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{
|
||||
"nfc": true
|
||||
}
|
||||
```
|
||||
|
||||
== [GET] /api/restart
|
||||
|
||||
Requires auth
|
||||
|
||||
== [GET] /api/factoryReset
|
||||
|
||||
Requires auth
|
||||
|
||||
== [GET] /api/logs
|
||||
|
||||
Requires auth
|
||||
|
||||
Returns a JSON array
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"time": "2026-02-03T18:48:50Z",
|
||||
"uid": "b1c3600"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
== [GET] /api/getToken
|
||||
|
||||
Retrieves the authentication token. _Only available in initial device setup._
|
||||
|
||||
If the token has already been retrieved (initial setup has been done), This
|
||||
endpoint will return 403 Forbidden.
|
||||
|
||||
Returns `text/plain` with the 16 characters token
|
||||
|
||||
@@ -9,72 +9,171 @@
|
||||
),
|
||||
)
|
||||
|
||||
#include "ปก.typ"
|
||||
#[
|
||||
#show raw.where(block: false): set text(font: "Laksaman", size: 10.5pt)
|
||||
#show raw.where(block: true): set block(fill: rgb("#282A36"), inset: 1.5em)
|
||||
#show raw.where(block: true): set raw(theme: "Dracula.tmTheme")
|
||||
#show raw.where(block: true): set text(
|
||||
fill: rgb("#F8F8F2"),
|
||||
font: "Cascadia Code",
|
||||
size: 10pt,
|
||||
)
|
||||
|
||||
#counter(page).update(1)
|
||||
#show: page-theme
|
||||
#include "Abstract.typ"
|
||||
#pagebreak()
|
||||
#include "Acknowledgements.typ"
|
||||
#pagebreak()
|
||||
#include "Cover.typ"
|
||||
|
||||
#show outline: set heading(outlined: true)
|
||||
#show outline.entry: it => {
|
||||
#counter(page).update(1)
|
||||
#show: page-theme
|
||||
#include "Abstract.typ"
|
||||
#pagebreak()
|
||||
#include "Acknowledgements.typ"
|
||||
#pagebreak()
|
||||
|
||||
#show outline: set heading(outlined: true)
|
||||
#show outline.entry: it => {
|
||||
show linebreak: [ ]
|
||||
link(
|
||||
it.element.location(),
|
||||
it.indented(it.prefix(), context [
|
||||
#it.body()
|
||||
#box(width: 1fr, repeat[.])
|
||||
#context thai-numbering(counter(page).at(it.element.location()).first())
|
||||
]),
|
||||
grid(
|
||||
columns: 3,
|
||||
column-gutter: 1fr,
|
||||
[#h(3.25em * (it.level - 1)) #it.prefix() #it.body()],
|
||||
h(1em),
|
||||
context page-numbering(counter(page).at(it.element.location()).first()),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#outline(depth: 2, indent: 3.75em)
|
||||
#[
|
||||
#set page(header: none)
|
||||
#show outline.entry: it => {
|
||||
it
|
||||
|
||||
#pagebreak()
|
||||
context {
|
||||
let outline-pages = counter(page).at(it.location()).first()
|
||||
let current-page = counter(page).get().first()
|
||||
|
||||
#import "@preview/i-figured:0.2.4"
|
||||
if current-page > outline-pages {
|
||||
fake-h1("สารบัญ (ต่อ)")
|
||||
v(1em)
|
||||
h(1fr)
|
||||
[หน้า]
|
||||
}
|
||||
}
|
||||
}
|
||||
#place(center, heading()[สารบัญ])
|
||||
#linebreak()
|
||||
#linebreak()
|
||||
#h(1fr)
|
||||
หน้า
|
||||
#outline(title: none, depth: 2, indent: 3.75em)
|
||||
]
|
||||
|
||||
#i-figured.outline(target-kind: table, title: [สารบัญตาราง])
|
||||
#pagebreak()
|
||||
|
||||
#pagebreak()
|
||||
#import "@preview/i-figured:0.2.4"
|
||||
|
||||
#i-figured.outline(
|
||||
title: [สารบัญภาพ],
|
||||
)
|
||||
#[
|
||||
#show outline.entry: it => {
|
||||
show linebreak: [ ]
|
||||
link(
|
||||
it.element.location(),
|
||||
grid(
|
||||
columns: 3,
|
||||
column-gutter: 1fr,
|
||||
[#h(3.25em * (it.level - 1)) #it.prefix().children.at(2) #it.body()],
|
||||
h(1em),
|
||||
context page-numbering(
|
||||
counter(page).at(it.element.location()).first(),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
#include "Chapter1.typ"
|
||||
#place(center, heading[สารบัญตาราง])
|
||||
#linebreak()
|
||||
#linebreak()
|
||||
ตารางที่
|
||||
#h(1fr)
|
||||
หน้า
|
||||
|
||||
#include "Chapter2/Chapter2.typ"
|
||||
#include "Chapter3.typ"
|
||||
#include "Chapter4.typ"
|
||||
#include "Chapter5.typ"
|
||||
#i-figured.outline(target-kind: table, title: none)
|
||||
|
||||
#bibliography("References.yaml", title: "บรรณานุกรม", full: true, style: "chicago-author-date")
|
||||
#pagebreak()
|
||||
|
||||
#pagebreak()
|
||||
#place(center, heading[สารบัญรูป])
|
||||
#linebreak()
|
||||
#linebreak()
|
||||
รูปที่
|
||||
#h(1fr)
|
||||
หน้า
|
||||
|
||||
= บรรณานุกรมภาพ
|
||||
#i-figured.outline(
|
||||
title: none,
|
||||
)
|
||||
]
|
||||
|
||||
#let image-credits() = context {
|
||||
#show heading: i-figured.reset-counters
|
||||
#show figure: i-figured.show-figure
|
||||
|
||||
#[
|
||||
#show figure.caption.where(position: bottom): it => place(
|
||||
center,
|
||||
it,
|
||||
dy: 2em,
|
||||
)
|
||||
#include "Chapter1.typ"
|
||||
#include "Chapter2/Chapter2.typ"
|
||||
#include "Chapter3/Chapter3.typ"
|
||||
#include "Chapter4.typ"
|
||||
#include "Chapter5.typ"
|
||||
]
|
||||
|
||||
#bibliography(
|
||||
"References.yaml",
|
||||
title: "บรรณานุกรม",
|
||||
full: true,
|
||||
style: "nktc-style.csl",
|
||||
)
|
||||
|
||||
#pagebreak()
|
||||
|
||||
= บรรณานุกรมภาพ
|
||||
|
||||
#let image-credits() = context {
|
||||
let figures = query(figure.where(kind: "i-figured-image"))
|
||||
let attributions = query(<afig>)
|
||||
let offset = 0
|
||||
|
||||
for (idx, f) in figures.enumerate() {
|
||||
if (idx >= attributions.len()) {
|
||||
if idx >= attributions.len() {
|
||||
return
|
||||
}
|
||||
|
||||
f.caption
|
||||
// f.counter.display(f.numbering)
|
||||
h(2.2em)
|
||||
attributions.at(idx).body.body
|
||||
}
|
||||
}
|
||||
if attributions.at(idx).body.body == [] {
|
||||
offset += 1
|
||||
|
||||
#image-credits()
|
||||
if idx + offset >= attributions.len() {
|
||||
return
|
||||
}
|
||||
|
||||
if attributions.at(idx + offset).body.body == [] {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
f.caption
|
||||
h(3.8em)
|
||||
|
||||
if (idx + offset >= 9) {
|
||||
h(0.5em)
|
||||
}
|
||||
|
||||
attributions.at(idx + offset).body.body
|
||||
linebreak()
|
||||
}
|
||||
}
|
||||
|
||||
#image-credits()
|
||||
]
|
||||
|
||||
#include "ภาคผนวก/ภาคผนวก.typ"
|
||||
#include "History.typ"
|
||||
|
||||
@@ -0,0 +1,406 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0" demote-non-dropping-particle="sort-only">
|
||||
<!-- This style was edited with the Visual CSL Editor (https://editor.citationstyles.org/visualEditor/) -->
|
||||
<info>
|
||||
<title>Nong Khai Technical College Project Guidelines</title>
|
||||
<title-short>NKTC</title-short>
|
||||
<id>http://www.zotero.org/styles/nong-khai-technical-college-project-guidelines</id>
|
||||
<link rel="self" href="http://www.zotero.org/styles/nong-khai-technical-college-project-guidelines"/>
|
||||
<link href="https://staticlines.dailitation.xyz/Documents/NKTCProjectGuidelines.pdf" rel="documentation"/>
|
||||
<author>
|
||||
<email>linesofcodes@dailitation.xyz</email>
|
||||
<name>Satakun Utama</name>
|
||||
</author>
|
||||
<category citation-format="numeric"/>
|
||||
<category field="engineering"/>
|
||||
<category field="generic-base"/>
|
||||
<summary>NKTC College Project Bibliography (Modified from IEEE)</summary>
|
||||
<updated>2025-12-27T05:32:04+00:00</updated>
|
||||
<rights license="http://creativecommons.org/licenses/by-sa/3.0/">This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License</rights>
|
||||
</info>
|
||||
<locale xml:lang="en">
|
||||
<date form="text">
|
||||
<date-part name="month" form="short" suffix=" "/>
|
||||
<date-part name="day" form="numeric-leading-zeros" suffix=", "/>
|
||||
<date-part name="year"/>
|
||||
</date>
|
||||
<terms>
|
||||
<term name="chapter" form="short">ch.</term>
|
||||
<term name="presented at">presented at the</term>
|
||||
<term name="available at">available</term>
|
||||
</terms>
|
||||
</locale>
|
||||
<macro name="status">
|
||||
<choose>
|
||||
<if variable="page issue volume" match="none">
|
||||
<text variable="status" text-case="capitalize-first" suffix="" font-weight="bold"/>
|
||||
</if>
|
||||
</choose>
|
||||
</macro>
|
||||
<macro name="edition">
|
||||
<choose>
|
||||
<if type="bill book chapter graphic legal_case legislation motion_picture paper-conference report song" match="any">
|
||||
<choose>
|
||||
<if is-numeric="edition">
|
||||
<group delimiter=" ">
|
||||
<number variable="edition" form="ordinal"/>
|
||||
<text term="edition" form="short"/>
|
||||
</group>
|
||||
</if>
|
||||
<else>
|
||||
<text variable="edition" text-case="capitalize-first" suffix="."/>
|
||||
</else>
|
||||
</choose>
|
||||
</if>
|
||||
</choose>
|
||||
</macro>
|
||||
<macro name="issued">
|
||||
<choose>
|
||||
<if type="article-journal report" match="any">
|
||||
<date variable="issued">
|
||||
<date-part name="month" form="short" suffix=" "/>
|
||||
<date-part name="year" form="long"/>
|
||||
</date>
|
||||
</if>
|
||||
<else-if type="bill book chapter graphic legal_case legislation song thesis" match="any">
|
||||
<date date-parts="year" variable="issued">
|
||||
<date-part name="year" form="long"/>
|
||||
</date>
|
||||
</else-if>
|
||||
<else-if type="paper-conference" match="any">
|
||||
<date variable="issued">
|
||||
<date-part name="month" form="short"/>
|
||||
<date-part name="year" prefix=" "/>
|
||||
</date>
|
||||
</else-if>
|
||||
<else-if type="motion_picture" match="any">
|
||||
<date variable="issued" form="text" prefix="(" suffix=")"/>
|
||||
</else-if>
|
||||
<else>
|
||||
<date variable="issued" form="text"/>
|
||||
</else>
|
||||
</choose>
|
||||
</macro>
|
||||
<macro name="author">
|
||||
<names variable="author">
|
||||
<name and="text" et-al-min="7" et-al-use-first="1" initialize="false" initialize-with=". "/>
|
||||
<label form="short" prefix=", " text-case="capitalize-first"/>
|
||||
<et-al font-style="italic"/>
|
||||
<substitute>
|
||||
<names variable="editor"/>
|
||||
<names variable="translator"/>
|
||||
</substitute>
|
||||
</names>
|
||||
</macro>
|
||||
<macro name="editor">
|
||||
<names variable="editor">
|
||||
<name initialize-with=". " delimiter=", " and="text"/>
|
||||
<label form="short" prefix=", " text-case="capitalize-first"/>
|
||||
</names>
|
||||
</macro>
|
||||
<macro name="locators">
|
||||
<group delimiter=", ">
|
||||
<text macro="edition"/>
|
||||
<group delimiter=" ">
|
||||
<text term="volume" form="short"/>
|
||||
<number variable="volume" form="numeric"/>
|
||||
</group>
|
||||
<group delimiter=" ">
|
||||
<number variable="number-of-volumes" form="numeric"/>
|
||||
<text term="volume" form="short" plural="true"/>
|
||||
</group>
|
||||
<group delimiter=" ">
|
||||
<text term="issue" form="short"/>
|
||||
<number variable="issue" form="numeric"/>
|
||||
</group>
|
||||
</group>
|
||||
</macro>
|
||||
<macro name="title">
|
||||
<choose>
|
||||
<if type="bill book graphic legal_case legislation motion_picture song" match="any">
|
||||
<text variable="title" font-style="normal" font-weight="bold"/>
|
||||
</if>
|
||||
<else>
|
||||
<text variable="title" quotes="false" font-weight="bold" suffix=" "/>
|
||||
</else>
|
||||
</choose>
|
||||
</macro>
|
||||
<macro name="publisher">
|
||||
<choose>
|
||||
<if type="bill book chapter graphic legal_case legislation motion_picture paper-conference song" match="any">
|
||||
<group delimiter="; ">
|
||||
<text variable="publisher-place"/>
|
||||
<text variable="publisher"/>
|
||||
</group>
|
||||
</if>
|
||||
<else>
|
||||
<group delimiter=", ">
|
||||
<text variable="publisher"/>
|
||||
<text variable="publisher-place"/>
|
||||
</group>
|
||||
</else>
|
||||
</choose>
|
||||
</macro>
|
||||
<macro name="event">
|
||||
<choose>
|
||||
<if type="paper-conference speech" match="any">
|
||||
<choose>
|
||||
<if variable="container-title" match="any">
|
||||
<group delimiter=", ">
|
||||
<group delimiter=" ">
|
||||
<text term="in"/>
|
||||
<text variable="container-title" font-style="italic"/>
|
||||
</group>
|
||||
<text variable="event-place"/>
|
||||
</group>
|
||||
</if>
|
||||
<else>
|
||||
<group delimiter=", ">
|
||||
<group delimiter=" ">
|
||||
<text term="presented at"/>
|
||||
<text variable="event"/>
|
||||
</group>
|
||||
<text variable="event-place"/>
|
||||
</group>
|
||||
</else>
|
||||
</choose>
|
||||
</if>
|
||||
</choose>
|
||||
</macro>
|
||||
<macro name="access">
|
||||
<choose>
|
||||
<if type="webpage post post-weblog" match="any">
|
||||
<choose>
|
||||
<if variable="URL">
|
||||
<group delimiter=" . " prefix=" ">
|
||||
<text variable="URL"/>
|
||||
<group delimiter=" ">
|
||||
<text term="accessed" text-case="capitalize-first"/>
|
||||
<date variable="accessed" form="text"/>
|
||||
</group>
|
||||
</group>
|
||||
</if>
|
||||
</choose>
|
||||
</if>
|
||||
<else-if match="any" variable="DOI">
|
||||
<text variable="DOI" prefix=" doi: " suffix="."/>
|
||||
</else-if>
|
||||
<else-if variable="URL">
|
||||
<group delimiter=". " prefix=" " suffix=". ">
|
||||
<group delimiter=" ">
|
||||
<text term="accessed" text-case="capitalize-first"/>
|
||||
<date variable="accessed" form="text"/>
|
||||
</group>
|
||||
<group prefix="[" suffix="]" delimiter=" ">
|
||||
<choose>
|
||||
<if variable="medium" match="any">
|
||||
<text variable="medium" text-case="capitalize-first"/>
|
||||
</if>
|
||||
<else>
|
||||
<text term="online" text-case="capitalize-first"/>
|
||||
<choose>
|
||||
<if type="motion_picture">
|
||||
<text term="video" text-case="capitalize-first"/>
|
||||
</if>
|
||||
</choose>
|
||||
</else>
|
||||
</choose>
|
||||
</group>
|
||||
</group>
|
||||
<group delimiter=": " prefix=" ">
|
||||
<text term="available at" text-case="capitalize-first"/>
|
||||
<text variable="URL"/>
|
||||
</group>
|
||||
</else-if>
|
||||
</choose>
|
||||
</macro>
|
||||
<macro name="page">
|
||||
<choose>
|
||||
<if type="article-journal" variable="number" match="all">
|
||||
<group delimiter=" ">
|
||||
<text value="Art."/>
|
||||
<text term="issue" form="short"/>
|
||||
<text variable="number"/>
|
||||
</group>
|
||||
</if>
|
||||
<else>
|
||||
<group delimiter=" ">
|
||||
<label variable="page" form="short"/>
|
||||
<text variable="page"/>
|
||||
</group>
|
||||
</else>
|
||||
</choose>
|
||||
</macro>
|
||||
<macro name="citation-locator">
|
||||
<group delimiter=" ">
|
||||
<choose>
|
||||
<if locator="page">
|
||||
<label variable="locator" form="short"/>
|
||||
</if>
|
||||
<else>
|
||||
<label variable="locator" form="short" text-case="capitalize-first"/>
|
||||
</else>
|
||||
</choose>
|
||||
<text variable="locator"/>
|
||||
</group>
|
||||
</macro>
|
||||
<macro name="geographic-location">
|
||||
<group delimiter=", " suffix=".">
|
||||
<choose>
|
||||
<if variable="publisher-place">
|
||||
<text variable="publisher-place" text-case="title"/>
|
||||
</if>
|
||||
<else-if variable="event-place">
|
||||
<text variable="event-place" text-case="title"/>
|
||||
</else-if>
|
||||
</choose>
|
||||
</group>
|
||||
</macro>
|
||||
<citation collapse="citation-number">
|
||||
<sort>
|
||||
<key variable="citation-number"/>
|
||||
</sort>
|
||||
<layout delimiter=", ">
|
||||
<group delimiter=", " prefix="(" suffix=")">
|
||||
<text variable="citation-number"/>
|
||||
<text macro="citation-locator"/>
|
||||
</group>
|
||||
</layout>
|
||||
</citation>
|
||||
<bibliography entry-spacing="0" second-field-align="flush">
|
||||
<layout>
|
||||
<text variable="citation-number" prefix="(" suffix=")"/>
|
||||
<text macro="author" suffix=" . "/>
|
||||
<choose>
|
||||
<if type="article-journal">
|
||||
<group delimiter=", ">
|
||||
<text macro="title"/>
|
||||
<text variable="container-title" font-style="italic" form="short"/>
|
||||
<text macro="locators"/>
|
||||
<text macro="page"/>
|
||||
<text macro="issued"/>
|
||||
<text macro="status"/>
|
||||
</group>
|
||||
<choose>
|
||||
<if variable="URL DOI" match="none">
|
||||
<text value="."/>
|
||||
</if>
|
||||
<else>
|
||||
<text value=","/>
|
||||
</else>
|
||||
</choose>
|
||||
<text macro="access"/>
|
||||
</if>
|
||||
<else-if type="paper-conference speech" match="any">
|
||||
<group delimiter=", " suffix=".">
|
||||
<text macro="title"/>
|
||||
<text macro="event"/>
|
||||
<text macro="issued"/>
|
||||
<text macro="locators"/>
|
||||
<text macro="page"/>
|
||||
<text macro="status"/>
|
||||
</group>
|
||||
<text macro="access"/>
|
||||
</else-if>
|
||||
<else-if type="report">
|
||||
<group delimiter=", " suffix=".">
|
||||
<text macro="title"/>
|
||||
<text macro="publisher"/>
|
||||
<group delimiter=" ">
|
||||
<text variable="genre"/>
|
||||
<text variable="number"/>
|
||||
</group>
|
||||
<text macro="issued"/>
|
||||
</group>
|
||||
<text macro="access"/>
|
||||
</else-if>
|
||||
<else-if type="thesis">
|
||||
<group delimiter=", " suffix=".">
|
||||
<text macro="title"/>
|
||||
<text variable="genre"/>
|
||||
<text macro="publisher"/>
|
||||
<text macro="issued"/>
|
||||
</group>
|
||||
<text macro="access"/>
|
||||
</else-if>
|
||||
<else-if type="webpage post-weblog post" match="any">
|
||||
<group delimiter=". " suffix=".">
|
||||
<text macro="title"/>
|
||||
<text variable="container-title" font-style="normal"/>
|
||||
<text macro="issued"/>
|
||||
</group>
|
||||
<text macro="access"/>
|
||||
</else-if>
|
||||
<else-if type="patent">
|
||||
<group delimiter=", ">
|
||||
<text macro="title"/>
|
||||
<text variable="number"/>
|
||||
<text macro="issued"/>
|
||||
</group>
|
||||
<text macro="access"/>
|
||||
</else-if>
|
||||
<else-if type="motion_picture">
|
||||
<text macro="geographic-location" suffix=". "/>
|
||||
<group delimiter=", " suffix=".">
|
||||
<text macro="title"/>
|
||||
<text macro="issued"/>
|
||||
</group>
|
||||
<text macro="access"/>
|
||||
</else-if>
|
||||
<else-if type="bill book graphic legal_case legislation report song" match="any">
|
||||
<group delimiter=" . " suffix=". ">
|
||||
<text macro="title"/>
|
||||
<text macro="locators"/>
|
||||
</group>
|
||||
<group delimiter=". " suffix=".">
|
||||
<text macro="publisher"/>
|
||||
<text macro="issued"/>
|
||||
<text macro="page"/>
|
||||
</group>
|
||||
<text macro="access"/>
|
||||
</else-if>
|
||||
<else-if type="article-magazine article-newspaper broadcast interview manuscript map patent personal_communication song speech thesis webpage" match="any">
|
||||
<group delimiter=", " suffix=".">
|
||||
<text macro="title"/>
|
||||
<text variable="container-title" font-style="italic"/>
|
||||
<text macro="locators"/>
|
||||
<text macro="publisher"/>
|
||||
<text macro="page"/>
|
||||
<text macro="issued"/>
|
||||
</group>
|
||||
<text macro="access"/>
|
||||
</else-if>
|
||||
<else-if type="chapter paper-conference" match="any">
|
||||
<group delimiter=". " suffix=". ">
|
||||
<text macro="title"/>
|
||||
<group delimiter=" ">
|
||||
<text term="in"/>
|
||||
<text variable="container-title" font-style="italic"/>
|
||||
</group>
|
||||
<text macro="locators"/>
|
||||
</group>
|
||||
<text macro="editor" suffix=" "/>
|
||||
<group delimiter=", " suffix=".">
|
||||
<text macro="publisher"/>
|
||||
<text macro="issued"/>
|
||||
<text macro="page"/>
|
||||
</group>
|
||||
<text macro="access"/>
|
||||
</else-if>
|
||||
<else>
|
||||
<group delimiter=", " suffix=". ">
|
||||
<text macro="title"/>
|
||||
<text variable="container-title" font-style="italic"/>
|
||||
<text macro="locators"/>
|
||||
</group>
|
||||
<group delimiter=", " suffix=".">
|
||||
<text macro="publisher"/>
|
||||
<text macro="page"/>
|
||||
<text macro="issued"/>
|
||||
</group>
|
||||
<text macro="access"/>
|
||||
</else>
|
||||
</choose>
|
||||
</layout>
|
||||
</bibliography>
|
||||
</style>
|
||||
@@ -0,0 +1,13 @@
|
||||
#pagebreak()
|
||||
#v(1fr)
|
||||
== บล็อคไดอะแกรม
|
||||
#v(1fr)
|
||||
#pagebreak()
|
||||
|
||||
#figure(
|
||||
image(
|
||||
"imgs/NFCAuthSystemWiring_bb.png",
|
||||
alt: "แผนผังการต่อวงจรภายในโปรแกรม Fritzing ของระบบยืนยันตัวตนด้วย NFC โดย ESP32 ถูกเชื่อมต่อกับบัซเซอร์และโมดูลตัวอ่าน NFC PN532 ผ่านโหมด SPI โดยทั้งสองส่วนประกอบมี breadboard เป็นตัวกลางในการเชื่อมต่อไฟบวกและไฟลบ (VCC/GND)",
|
||||
),
|
||||
caption: [แผนผังการต่อวงจร],
|
||||
)
|
||||
@@ -0,0 +1,30 @@
|
||||
#import "../PageTemplate.typ": *
|
||||
#show: page-theme.with(has-header: false)
|
||||
|
||||
#v(1fr)
|
||||
== งบประมาณในการจัดทำเครื่องยืนยันตัวตนด้วย NFC
|
||||
#v(1fr)
|
||||
#pagebreak()
|
||||
|
||||
#show: page-theme
|
||||
|
||||
*งบประมาณในการจัดทำเครื่องยืนยันตัวตนด้วย NFC*
|
||||
|
||||
#table(
|
||||
columns: (2em, 3fr, 1fr, 1fr, 1fr),
|
||||
align: (center, left, center, center, center),
|
||||
[ที่], table.cell(align: center)[รายการ], [จำนวน], [หน่วย], [ราคา (บาท)],
|
||||
[1], [ESP32 NodeMCU ESP-WROOM-32 Wi-Fi and Bluetooth], [1], [175], [175],
|
||||
|
||||
[2], [Active Buzzer ลำโพงสัญญาณ 5V TMB12A05 12*9.5mm], [1], [6], [6],
|
||||
|
||||
[3], [PIR Motion Sensor HC-SR501], [1], [40], [40],
|
||||
|
||||
[4], [เซนเซอร์ NFC PN532 Module Set], [2], [79], [158],
|
||||
|
||||
[5], [แผ่นไม้], [4], [20], [80],
|
||||
|
||||
[6], [กล่องพลาสติก], [3], [40], [120],
|
||||
|
||||
table.cell(colspan: 4, align: left)[*รวมค่าใช้จ่าย*], [579],
|
||||
)
|
||||
@@ -1,4 +1,18 @@
|
||||
= ประวัติย่อผู้จัดทำ
|
||||
#import "../PageTemplate.typ": *
|
||||
|
||||
#set text(font: "Laksaman", size: 10.5pt)
|
||||
#set par(leading: 1em)
|
||||
#show heading: set text(size: 10.5pt)
|
||||
#pagebreak()
|
||||
#v(1fr)
|
||||
== ประวัติย่อผู้จัดทำ
|
||||
#v(1fr)
|
||||
#pagebreak()
|
||||
#show: page-theme.with(has-header: true)
|
||||
#show heading.where(level: 3): set text(weight: "bold")
|
||||
#show heading.where(level: 3): set align(center)
|
||||
|
||||
#heading(outlined: false, level: 3)[ประวัติย่อผู้จัดทำ]
|
||||
|
||||
#place(right, box(stroke: (thickness: 1pt), width: 0.8in, height: 1in))
|
||||
|
||||
@@ -7,26 +21,38 @@
|
||||
row-gutter: 1em,
|
||||
column-gutter: 2em,
|
||||
[ชื่อ], [นางสาวประภากร ศรีวรสาร],
|
||||
[เกิด], [วันที่ 2 ตุลาคม พ.ศ.255x],
|
||||
[เกิด], [วันที่ 2 ตุลาคม พ.ศ.2551],
|
||||
[ที่อยู่],
|
||||
[
|
||||
บ้านเลขที่ ก หมู่ที่ ข ตำบล ค\
|
||||
อำเภอ ง จังหวัด หนองคาย
|
||||
บ้านเลขที่ 192 หมู่ที่ 15 ตำบล ในเมือง\
|
||||
อำเภอ เมืองหนองคาย จังหวัด หนองคาย
|
||||
],
|
||||
)
|
||||
|
||||
#linebreak()
|
||||
*ประวัติการศึกษา*
|
||||
|
||||
#grid(
|
||||
columns: 3,
|
||||
row-gutter: 1em,
|
||||
column-gutter: 2em,
|
||||
[พ.ศ.25xx], [ป.6], [โรงเรียน x],
|
||||
[พ.ศ.25xx], [ม.3], [โรงเรียน y],
|
||||
[พ.ศ.2564], [ป.6], [โรงเรียน อนุบาลหนองคาย],
|
||||
[พ.ศ.2567], [ม.3], [โรงเรียน ปทุมเทพวิทยาคาร],
|
||||
[พ.ศ.2569], [ปวช.], [สาขาวิชาช่างเทคนิคคอมพิวเตอร์ วิทยาลัยเทคนิคหนองคาย],
|
||||
)
|
||||
|
||||
#v(1in)
|
||||
#linebreak()
|
||||
*ประวัติการฝึกงาน*
|
||||
|
||||
#grid(
|
||||
columns: 2,
|
||||
row-gutter: 1em,
|
||||
column-gutter: 2em,
|
||||
[พ.ศ. 2569], [ฝึกงานโรงพยาบาลหนองคาย],
|
||||
)
|
||||
|
||||
#pagebreak()
|
||||
#heading(outlined: false, level: 3)[ประวัติย่อผู้จัดทำ]
|
||||
|
||||
#place(right, box(stroke: (thickness: 1pt), width: 0.8in, height: 1in))
|
||||
|
||||
@@ -43,6 +69,7 @@
|
||||
],
|
||||
)
|
||||
|
||||
#linebreak()
|
||||
*ประวัติการศึกษา*
|
||||
|
||||
#grid(
|
||||
@@ -54,7 +81,18 @@
|
||||
[พ.ศ.2569], [ปวช.], [สาขาวิชาช่างเทคนิคคอมพิวเตอร์ วิทยาลัยเทคนิคหนองคาย],
|
||||
)
|
||||
|
||||
#v(1in)
|
||||
#linebreak()
|
||||
*ประวัติการฝึกงาน*
|
||||
|
||||
#grid(
|
||||
columns: 2,
|
||||
row-gutter: 1em,
|
||||
column-gutter: 2em,
|
||||
[พ.ศ. 2569], [ฝึกงานที่ไอทีเซอร์วิซ ฟิกซ์เซ็นเตอร์],
|
||||
)
|
||||
|
||||
#pagebreak()
|
||||
#heading(outlined: false, level: 3)[ประวัติย่อผู้จัดทำ]
|
||||
|
||||
#place(right, box(stroke: (thickness: 1pt), width: 0.8in, height: 1in))
|
||||
|
||||
@@ -71,6 +109,7 @@
|
||||
],
|
||||
)
|
||||
|
||||
#linebreak()
|
||||
*ประวัติการศึกษา*
|
||||
|
||||
#grid(
|
||||
@@ -81,3 +120,13 @@
|
||||
[พ.ศ.2567], [ม.3], [โรงเรียนหัสดีศึกษา],
|
||||
[พ.ศ.2569], [ปวช.], [สาขาวิชาช่างเทคนิคคอมพิวเตอร์ วิทยาลัยเทคนิคหนองคาย],
|
||||
)
|
||||
|
||||
#linebreak()
|
||||
*ประวัติการฝึกงาน*
|
||||
|
||||
#grid(
|
||||
columns: 2,
|
||||
row-gutter: 1em,
|
||||
column-gutter: 2em,
|
||||
[พ.ศ. 2569], [ฝึกงานที่ร้าน ทูโฟร์อิ้งค์],
|
||||
)
|
||||
@@ -0,0 +1,58 @@
|
||||
#import "../PageTemplate.typ": *
|
||||
#show: page-theme.with(has-header: false)
|
||||
|
||||
#v(1fr)
|
||||
== โปรแกรม
|
||||
#v(1fr)
|
||||
#pagebreak()
|
||||
|
||||
#show: page-theme
|
||||
|
||||
*โปรแกรมเครื่องยืนยันตัวตนด้วย NFC*
|
||||
|
||||
#show heading.where(level: 3): set heading(numbering: (..n) => {
|
||||
str(n.at(-1))
|
||||
[. ]
|
||||
})
|
||||
|
||||
1. Android Studio
|
||||
|
||||
#afigure(
|
||||
image("imgs/Android_Studio_icon_(2023).svg"),
|
||||
attr: [Android Studio, CC BY 2.5 Generic],
|
||||
alt: "โลโก Android Studio",
|
||||
caption: [Android Studio],
|
||||
)
|
||||
|
||||
2. CLion
|
||||
|
||||
#afigure(
|
||||
image("imgs/CLion.svg"),
|
||||
attr: [JetBrains เป็นเจ้าของเครื่องหมายการค้า CLion],
|
||||
alt: "โลโก CLion",
|
||||
caption: [JetBrains CLion],
|
||||
)
|
||||
|
||||
3. PlatformIO
|
||||
|
||||
#afigure(
|
||||
image("imgs/platformio-logo.png", width: 1.5in),
|
||||
alt: "โลโก PlatformIO",
|
||||
caption: [PlatformIO],
|
||||
)
|
||||
|
||||
4. liteauthconfig
|
||||
|
||||
#figure(
|
||||
image("imgs/liteauthconfig_deviceinfo_desktop.png", width: 3.5in),
|
||||
alt: "หน้าอุปกรณ์ข้อมูลของแอพลิเคชัน liteauthconfig บนเดสก์ท็อป",
|
||||
caption: [liteauthconfig บนเดสก์ท็อป],
|
||||
)
|
||||
|
||||
5. liteauth-firmware
|
||||
|
||||
#figure(
|
||||
image("imgs/liteauthfirmware_clion.png", width: 5in),
|
||||
alt: "รูปแสดงโคด lite auth firmware ที่เปิดอยู่ภายใน CLion",
|
||||
caption: [โคด liteauth-firmware],
|
||||
)
|
||||
@@ -0,0 +1,116 @@
|
||||
#import "@preview/tiaoma:0.3.0": qrcode
|
||||
#import "../PageTemplate.typ": *
|
||||
#show: page-theme.with(has-header: false)
|
||||
|
||||
#v(1fr)
|
||||
== คู่มือการใช้งาน
|
||||
#v(1fr)
|
||||
#pagebreak()
|
||||
|
||||
#show: page-theme
|
||||
#show heading.where(level: 3): set text(weight: "bold")
|
||||
#show heading.where(level: 4): it => {
|
||||
block(
|
||||
it,
|
||||
inset: (left: 3em * (it.level - 3)),
|
||||
)
|
||||
}
|
||||
#set enum(indent: 3em)
|
||||
|
||||
#text("คู่มือการใช้งานเครื่องยืนยันตัวตนด้วย NFC", size: 12pt, weight: "bold")
|
||||
|
||||
=== การเปิดใช้อุปกรณ์
|
||||
|
||||
ทำการเสียบสายชาร์จของอุปกรณ์
|
||||
|
||||
=== การใช้งานแอพลิเคชัน
|
||||
|
||||
#grid(
|
||||
columns: 2,
|
||||
column-gutter: 2em,
|
||||
[
|
||||
==== การติดตั้งแอพลิเคชัน
|
||||
1. ไปยัง
|
||||
https://gitskette.dailitation.xyz/linesofcodes/liteauthconfig/releases
|
||||
หรือสแกน QR code ด้านข้าง
|
||||
2. เลือกเวอร์ชันล่าสุด และดาวน์โหลดไฟล์นามสกุล .apk
|
||||
3. ติดตั้งไฟล์ .apk
|
||||
],
|
||||
qrcode(
|
||||
"https://gitskette.dailitation.xyz/linesofcodes/liteauthconfig/releases",
|
||||
),
|
||||
)
|
||||
|
||||
==== การตั้งค่าอุปกรณ์
|
||||
|
||||
#grid(
|
||||
columns: 2,
|
||||
column-gutter: 2em,
|
||||
[
|
||||
1. เชื่อมต่อเครือข่ายไร้สายที่ต้องการให้อุปกรณ์เชื่อมต่อ
|
||||
2. เพื่อลงทะเบียนอุปกรณ์ กดปุ่มสัญลักษณ์บวก
|
||||
3. กด _ตั้งค่าอุปกรณ์ใหม่_
|
||||
4. อาจมีไดอะล็อกถามเกี่ยวกับข้อมูลเครือข่าย
|
||||
หากต้องการให้แอพลิเคชันกรอกข้อมูลเครือข่ายโดยอัตโนมัติ แตะ _ดำเนินการต่อ_#jb
|
||||
แอพลิเคชันจะขออนุญาตในการเข้าถึงตำแหน่งอย่างละเอียดเนื่องจากจำเป็นในการเข้าถึงข้อมูลเครือข่าย
|
||||
5. ตั้งชื่อให้แก่อุปกรณ์
|
||||
6. หากปฏิเสธการกรอกข้อมูลเครือข่ายอัตโนมัติ กรอก SSID และ BSSID
|
||||
ของเครือข่ายที่ต้องการให้อุปกรณ์เชื่อมต่อ
|
||||
7. กรอกรหัสผ่านเครือข่าย
|
||||
8. คลิกปุ่มเครื่องหมายติ๊กถูก
|
||||
9. รอกระบวณการการตั้งค่าเครือข่าย
|
||||
],
|
||||
figure(
|
||||
image("imgs/th-mobile-home-empty.png", width: 1.5in),
|
||||
caption: [เมื่อเปิดแอพลิเคชันเป็นครั้งแรก],
|
||||
),
|
||||
)
|
||||
|
||||
#pagebreak()
|
||||
|
||||
==== การตรวจสอบสถานะอุปกรณ์
|
||||
|
||||
#grid(
|
||||
columns: 2,
|
||||
column-gutter: 2em,
|
||||
[
|
||||
#i หน้าสถานะอุปกรณ์ประกอบไปด้วยข้อมูลดังนี้
|
||||
|
||||
1. สถานะอุปกรณ์
|
||||
2. ข้อมูลเครือข่ายอุปกรณ์
|
||||
3. รายการกิจกรรม
|
||||
],
|
||||
)
|
||||
|
||||
==== การจัดการอุปกรณ์
|
||||
|
||||
#grid(
|
||||
columns: 2,
|
||||
column-gutter: 2em,
|
||||
[
|
||||
1. รีเฟรช ทำการรีเฟรชรายการกิจกรรมของอุปกรณ์
|
||||
2. จัดการโทเค็น ทำการแสดงหรือแก้ไขโทเค็นที่ถูกใช้ในการสื่อสารกับอุปกรณ์
|
||||
3. ตั้งค่าเครือข่ายใหม่
|
||||
ใช้ในกรณีที่เครือข่ายมีการเปลี่ยนแปลงและอุปกรณ์ไม่สามารถเชื่อมต่อเครือข่ายเดิมได้
|
||||
4. คืนค่าโรงงาน ลบข้อมูลทั้งหมดบนอุปกรณ์
|
||||
5. ลบ ทำการลืมอุปกรณ์นี้
|
||||
],
|
||||
figure(
|
||||
image("imgs/th-mobile-device-actions.png", width: 1.5in),
|
||||
caption: [รายการการกระทำต่ออุปกรณ์],
|
||||
),
|
||||
)
|
||||
|
||||
#v(4em)
|
||||
|
||||
==== การคืนค่าโรงงาน
|
||||
|
||||
#i การคืนค่าโรงงานจะส่งผลให้อุปกรณ์ยืนยันตัวตนกลับสู่ค่าเริ่มต้น โดยหลังจากกดใช้แล้ว
|
||||
ผู้ใช้สามารถเลือกที่จะใช้ฟังก์ชันตั้งค่าเครือข่ายใหม่ หรือทำการลบอุปกรณ์ได้
|
||||
|
||||
=== ข้อจำกัดทางเครือข่าย
|
||||
|
||||
1. อุปกรณ์ยืนยันตัวตนสามารถเชื่อมต่อเครือข่ายย่านความถี่ 2.4 GHz ที่รองรับมาตรฐาน Wi-Fi 2, 3,
|
||||
และ 4 (802.11b/g/n) ได้เท่านั้น
|
||||
2. เนื่องจากข้อจำกัดของเทคโนโลยี mDNS
|
||||
หลังจากการตั้งค่าเครือข่ายอุปกรณ์อาจมีความล่าช้าในการอัปเดตสถานะอุปกรณ์
|
||||
@@ -0,0 +1,10 @@
|
||||
<svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path opacity="0.2" d="M49.8535 123.492C47.8751 123.023 46.2193 121.926 43.9021 119.549C40.0315 115.578 36.8904 113.925 31.4309 112.985C25.7674 112.01 23.2506 109.905 21.7375 104.877C19.8698 98.6708 17.9177 95.6985 13.6285 92.5305C8.7629 88.9366 7.51452 85.7674 8.70211 80.0242C9.80208 74.7048 9.38087 70.9229 7.14689 66.0604C4.48145 60.2587 4.81049 57.1586 8.5962 52.4053C12.0668 48.0478 13.1561 45.1674 13.6759 38.9737C14.2004 32.7233 15.9394 30.159 21.0608 28.0837C25.3351 26.3518 28.9917 23.3452 31.0189 19.8957C33.3632 15.9068 33.7054 15.4495 35.1579 14.3658C37.5018 12.6171 39.3969 12.1325 43.0061 12.3588C49.2755 12.7519 52.6358 11.9991 56.846 9.25832C62.3354 5.68473 65.6639 5.68473 71.1534 9.25832C75.3636 11.9991 78.7239 12.7519 84.9933 12.3588C90.922 11.987 93.389 13.5434 97.0028 19.9355C98.7937 23.1032 102.454 26.1862 106.461 27.9007C112.167 30.3428 113.825 32.5717 114.246 38.3638C114.702 44.6367 115.988 48.144 119.395 52.4053C123.189 57.1501 123.52 60.2531 120.852 66.0604C118.619 70.9229 118.197 74.7048 119.297 80.0242C120.485 85.7674 119.236 88.9366 114.371 92.5305C110.082 95.6985 108.13 98.6708 106.262 104.877C104.749 109.905 102.232 112.01 96.5685 112.985C91.0974 113.927 87.9527 115.585 84.0973 119.562C79.8233 123.969 76.7594 124.697 70.7842 122.721C65.8971 121.106 62.1344 121.099 57.2668 122.697C53.8571 123.816 52.0396 124.011 49.8535 123.492V123.492Z" fill="black"/>
|
||||
<path d="M49.8535 122.321C47.8751 121.851 46.2193 120.754 43.9021 118.377C40.0315 114.407 36.8904 112.753 31.4309 111.814C25.7674 110.839 23.2506 108.733 21.7375 103.706C19.8698 97.499 17.9177 94.5267 13.6285 91.3586C8.7629 87.7647 7.51452 84.5955 8.70211 78.8524C9.80208 73.5329 9.38087 69.751 7.14689 64.8885C4.48145 59.0868 4.81049 55.9867 8.5962 51.2335C12.0668 46.8759 13.1561 43.9955 13.6759 37.8018C14.2004 31.5514 15.9394 28.9871 21.0608 26.9119C25.3351 25.1799 28.9917 22.1733 31.0189 18.7238C33.3632 14.7349 33.7054 14.2776 35.1579 13.194C37.5018 11.4452 39.3969 10.9606 43.0061 11.1869C49.2755 11.58 52.6358 10.8273 56.846 8.08645C62.3354 4.51285 65.6639 4.51285 71.1534 8.08645C75.3636 10.8273 78.7239 11.58 84.9933 11.1869C90.922 10.8151 93.389 12.3715 97.0028 18.7636C98.7937 21.9314 102.454 25.0143 106.461 26.7289C112.167 29.1709 113.825 31.3998 114.246 37.192C114.702 43.4648 115.988 46.9721 119.395 51.2335C123.189 55.9782 123.52 59.0812 120.852 64.8885C118.619 69.751 118.197 73.5329 119.297 78.8524C120.485 84.5955 119.236 87.7647 114.371 91.3586C110.082 94.5267 108.13 97.499 106.262 103.706C104.749 108.733 102.232 110.839 96.5685 111.814C91.0974 112.755 87.9527 114.414 84.0973 118.39C79.8233 122.798 76.7594 123.525 70.7842 121.55C65.8971 119.934 62.1344 119.927 57.2668 121.525C53.8571 122.644 52.0396 122.839 49.8535 122.321V122.321Z" fill="white"/>
|
||||
<path d="M85.0051 59.0295C84.6361 58.2764 84.9524 57.3728 85.7054 57.0038C86.4584 56.6349 87.362 56.9511 87.731 57.7041C88.1 58.4572 87.7837 59.3608 87.0307 59.7298C86.2777 60.0987 85.3741 59.7825 85.0051 59.0295ZM92.332 74.0898C91.963 73.3368 92.2792 72.4332 93.0323 72.0642C93.7853 71.6952 94.6889 72.0115 95.0579 72.7645C95.4269 73.5175 95.1106 74.4211 94.3576 74.7901C93.6046 75.1591 92.7009 74.8428 92.332 74.0898ZM92.972 54.549C88.1527 51.1077 81.865 50.2192 76.0442 52.4707L91.9554 85.1893C97.3169 82.004 100.495 76.4995 100.766 70.5883L106.805 71.0175C107.151 71.0401 107.453 70.7841 107.475 70.4301C107.498 70.0837 107.242 69.7825 106.888 69.76L100.773 69.3232C100.713 66.7479 100.096 64.1199 98.8681 61.5897C97.6407 59.0671 95.954 56.9587 93.966 55.3171L97.3998 50.2342C97.5955 49.9481 97.5202 49.5565 97.2341 49.3607C96.948 49.1649 96.5564 49.2402 96.3606 49.5264L92.972 54.5415" fill="#3DDC84"/>
|
||||
<path d="M78.3033 66.8683C73.8153 69.037 68.9884 70.1364 63.9583 70.1364C52.6254 70.1364 42.3316 64.3834 36.3301 55.2267C35.8557 54.5038 34.8768 54.3306 34.1765 54.8426L28.4008 59.0972C27.7457 59.5791 27.5951 60.4978 28.0544 61.1755C35.9385 72.9452 49.2895 80.3172 63.9583 80.3172C70.5321 80.3172 76.8499 78.8789 82.731 76.0401L78.3033 66.8683Z" fill="#4285F4"/>
|
||||
<path d="M63.9057 30.6708H67.0307V23.7656C67.0307 22.0412 65.6301 20.6406 63.9057 20.6406C62.1813 20.6406 60.7806 22.0412 60.7806 23.7656V30.6708H63.9057Z" fill="#4285F4"/>
|
||||
<path d="M55.7729 44.1499L34.2893 88.367C33.8225 89.3234 33.574 90.3625 33.5514 91.4243L33.4234 97.215C33.3932 98.7135 35.1252 99.5569 36.2848 98.6081L40.7577 94.9334C41.5785 94.2632 42.2412 93.4198 42.7081 92.4635L63.8829 48.8713L55.7804 44.1574L55.7729 44.1499Z" fill="#4285F4"/>
|
||||
<path d="M94.2671 91.4167C94.2445 90.355 93.9885 89.3158 93.5292 88.3595L72.0456 44.1423L63.9431 48.8713L85.118 92.4484C85.5848 93.4047 86.2475 94.2406 87.0683 94.9183L91.5412 98.593C92.7008 99.5418 94.4403 98.6984 94.4027 97.1999L94.2747 91.4092L94.2671 91.4167Z" fill="#4285F4"/>
|
||||
<path d="M63.9053 30.1211C58.7321 30.1211 54.5303 34.3305 54.5303 39.4962C54.5303 44.6619 58.7396 48.8713 63.9053 48.8713C69.071 48.8713 73.2804 44.6619 73.2804 39.4962C73.2804 34.3305 69.071 30.1211 63.9053 30.1211ZM63.9053 44.6544C61.0665 44.6544 58.7472 42.3426 58.7472 39.4962C58.7472 36.6498 61.0589 34.338 63.9053 34.338C66.7517 34.338 69.0635 36.6498 69.0635 39.4962C69.0635 42.3426 66.7517 44.6544 63.9053 44.6544Z" fill="#073042"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.2 KiB |
@@ -0,0 +1,20 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="226" height="79" fill="none" viewBox="0 0 226 79">
|
||||
<defs>
|
||||
<linearGradient id="a" x1="3.98138" x2="62.6868" y1="4.22438" y2="62.9293" gradientUnits="userSpaceOnUse">
|
||||
<stop offset=".29" stop-color="#009AE5"/>
|
||||
<stop offset=".7" stop-color="#00D980"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="b" x1="56.3788" x2="2.75258" y1="-.71738" y2="24.1455" gradientUnits="userSpaceOnUse">
|
||||
<stop offset=".3" stop-color="#FF318C"/>
|
||||
<stop offset=".54" stop-color="#009AE5"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path fill="#000" fill-rule="evenodd" d="M98.1941 21.33c-1.84 0-3.51.46-5 1.38v-.01c-1.49.92-2.66 2.19-3.5 3.81-.84 1.62-1.26 3.44-1.26 5.47s.42 3.85 1.26 5.47c.84 1.62 2.01 2.89 3.5 3.81 1.49.92 3.16 1.38 5 1.38 1.36 0 2.6099-.22 3.7799-.68 1.17-.46 2.17-1.11 3-1.97.83-.86 1.46-1.86 1.87-3h5.61c-.49 2.06-1.39 3.88-2.73 5.47-1.34 1.59-3 2.82-5 3.7-2 .88-4.19 1.32-6.5699 1.32-2.86 0-5.44-.67-7.74-2.02-2.31-1.34-4.12-3.2-5.44-5.56-1.32-2.36-1.98-5-1.98-7.91s.66-5.55 1.98-7.91c1.32-2.36 3.14-4.21 5.44-5.56 2.31-1.35 4.89-2.02 7.74-2.02 2.3799 0 4.5699.44 6.5699 1.32 2 .87 3.66 2.11 5 3.7 1.34 1.59 2.25 3.42 2.73 5.47h-5.61c-.41-1.15-1.03-2.14-1.87-3-.84-.86-1.83-1.51-3-1.97-1.17-.46-2.4199-.69-3.7799-.69ZM121.904 17h.01l-.01-.01V17Zm0 0h-5.3v29.96h19.75v-4.82h-14.45V17Zm22.51 29.97h-5.05V25.05h5.05v21.92Zm.35-24.23h-5.76v-5.01h5.76v5.01Zm14.77 1.8c2.15 0 4.11.5 5.86 1.5s3.13 2.37 4.14 4.12c1.01 1.74 1.51 3.7 1.51 5.85 0 2.15-.5 4.1-1.51 5.85s-2.38 3.12-4.14 4.12c-1.76 1-3.74 1.5-5.89 1.5-2.15 0-4.11-.5-5.86-1.5s-3.13-2.37-4.14-4.12c-1.01-1.74-1.51-3.7-1.51-5.85 0-2.15.5-4.1 1.5-5.85s2.38-3.12 4.14-4.12c1.77-1 3.75-1.5 5.9-1.5Zm3.26 17.55c.95-.58 1.69-1.4 2.21-2.46s.78-2.25.78-3.62-.26-2.58-.79-3.63c-.52-1.05-1.26-1.87-2.21-2.46-.95-.59-2.04-.89-3.26-.89-1.22 0-2.31.3-3.26.88-.95.58-1.68 1.4-2.2 2.46-.52 1.06-.78 2.28-.78 3.64 0 1.36.26 2.56.78 3.62.52 1.05 1.25 1.88 2.2 2.46.94.59 2.04.88 3.26.88 1.22 0 2.32-.3 3.27-.88Zm27.78-16.52c1.18.68 2.1 1.67 2.76 2.97l.01.03c.65 1.29.98 2.84.98 4.64v13.78h-5.03V33.98c0-1.06-.18-1.96-.54-2.7-.36-.74-.87-1.31-1.54-1.7-.67-.39-1.47-.59-2.4-.59-1 0-1.88.22-2.65.67-.77.45-1.37 1.07-1.79 1.88-.42.81-.63 1.72-.63 2.75v12.69h-5.05V25.06h4.9v3.21c.63-1.06 1.45-1.92 2.45-2.55 1.25-.79 2.72-1.18 4.4-1.18 1.57 0 2.95.34 4.13 1.03ZM87.7041 74.22c.17-.31.25-.66.25-1.05h.01v-9.15h3.1v9.37c0 .88-.2 1.67-.61 2.38s-.97 1.26-1.68 1.66c-.71.4-1.52.6-2.41.6h-2.37v-2.85h1.95c.4 0 .75-.08 1.05-.25.31-.17.54-.4.71-.71Zm15.2599-1.9h-6.4999v3.02h7.3799v2.7H93.4441V64.02h10.1999v2.71h-7.1799v2.97h6.4999v2.62Zm6.16-5.52h-4.16v-2.78h11.39v2.78h-4.13v11.23h-3.1V66.8Zm17.2 3.9c.29.08.56.18.81.31h.01c.57.31 1.02.73 1.34 1.28.32.55.48 1.17.48 1.86 0 .75-.2 1.42-.61 2.01-.41.59-.98 1.05-1.72 1.38-.74.33-1.58.5-2.52.5h-6.35V64.02h6.23c.89 0 1.69.16 2.39.47.7.31 1.24.75 1.63 1.31.39.56.58 1.2.58 1.91 0 .62-.15 1.17-.44 1.65-.29.48-.7.86-1.21 1.12-.179.0945-.386.1533-.585.2101l-.035.0099Zm-2.8-4.33h-2.75v3.45h2.75c.38 0 .72-.08 1.01-.22.3-.14.52-.34.69-.61.17-.27.25-.59.25-.93 0-.34-.09-.64-.25-.89-.17-.26-.4-.45-.69-.59-.29-.14-.63-.21-1.01-.21Zm1.24 9.1c.32-.15.57-.35.75-.62v.02c.18-.27.27-.57.27-.93 0-.36-.09-.68-.27-.96-.18-.28-.44-.5-.76-.65-.33-.15-.7-.23-1.11-.23h-2.87v3.59h2.87c.42 0 .8-.07 1.12-.22Zm16.56-4.67c-.43.67-1.03 1.2-1.81 1.57h-.01c-.14.07-.3.13-.46.19l3.2 5.48h-3.54l-2.84-5.11h-2.02v5.11h-3.1V64.02h6.14c1.01 0 1.9.18 2.67.55.77.37 1.36.89 1.78 1.56.42.67.63 1.43.63 2.32 0 .89-.21 1.68-.64 2.35Zm-3.56-.61c.32-.16.57-.39.74-.68v.01c.17-.29.26-.63.26-1.03s-.09-.74-.26-1.03c-.17-.29-.42-.51-.74-.67-.32-.15-.7-.23-1.13-.23h-2.79v3.87h2.79c.43 0 .81-.08 1.13-.24Zm5.51 7.85 5.01-14.02h3.36l5.12 14.02h-3.09l-1.06-3.09h-5.2l-.99 3.09h-3.15Zm6.46-10.39-1.61 4.95h3.71l-1.72-4.95-.19-.9-.19.9Zm11.43 10.39h-3.2V64.02h3.2v14.02Zm5.44-14.02 6.02 9.48h.01v-9.48h2.83v14.02h-3.05l-6-9.48v9.48h-2.83V64.02h3.02Zm17.78 5.66c.71.13 1.33.4 1.88.79v-.02c.55.4.97.88 1.28 1.47.31.59.46 1.23.46 1.92 0 .85-.23 1.61-.68 2.28-.45.67-1.08 1.2-1.88 1.58-.81.38-1.74.57-2.77.57s-1.95-.19-2.75-.56c-.8-.37-1.43-.9-1.89-1.56-.46-.66-.7-1.44-.71-2.31h3.1c0 .36.1.68.29.96.19.28.46.49.81.64.35.15.75.23 1.18.23.43 0 .8-.07 1.12-.2.32-.13.56-.32.74-.57.18-.25.27-.53.27-.84 0-.39-.12-.71-.36-.97s-.57-.44-.98-.54l-2.52-.52c-.66-.14-1.24-.39-1.74-.75s-.89-.82-1.16-1.36c-.27-.55-.41-1.16-.41-1.83 0-.84.22-1.58.64-2.23.43-.65 1.02-1.16 1.78-1.53.76-.37 1.62-.55 2.6-.55s1.86.18 2.62.53c.76.35 1.36.84 1.79 1.47.43.62.66 1.35.68 2.16h-3.1c0-.3-.09-.57-.25-.81-.17-.24-.4-.42-.69-.55-.29-.14-.64-.2-1.02-.2s-.72.07-1.01.19c-.29.12-.52.3-.68.52-.16.23-.24.49-.24.79 0 .34.11.61.33.84.22.23.52.38.89.47l2.38.49Zm14.38 8.36h-3.2V64.02h3.2v14.02Zm7.88-14.02c1.33 0 2.53.31 3.59.91 1.06.61 1.9 1.44 2.5 2.51.61 1.06.91 2.27.91 3.59 0 1.32-.31 2.52-.91 3.59-.6 1.07-1.43 1.9-2.5 2.51-1.07.61-2.26.91-3.59.91h-5.47V64.02h5.47Zm2.01 10.86c.58-.35 1.03-.85 1.34-1.5v-.01c.31-.65.47-1.44.47-2.35 0-.91-.16-1.7-.47-2.35-.31-.65-.76-1.15-1.34-1.5-.58-.35-1.26-.52-2.05-.52h-2.32v8.75h2.32c.79 0 1.47-.17 2.05-.52Zm9.8-2.56v3.02h7.38v2.7h-10.4V64.02h10.2v2.71h-7.18v2.97h6.5v2.62h-6.5Z" clip-rule="evenodd"/>
|
||||
<path fill="url(#a)" d="M64 59.9294V25.9611c0-1.6291-.9711-3.1017-2.4681-3.7434L24.0413 6.14962c-.5068-.21702-1.0531-.32931-1.6046-.32931H4.07273C1.82342 5.82031 0 7.64373 0 9.89304V27.859c0 .8047.238545 1.5913.685382 2.261L22.0887 62.1886c.7552 1.1322 2.0265 1.8118 3.3874 1.8118l34.4512.0017c2.2493 0 4.0727-1.8234 4.0727-4.0727Z"/>
|
||||
<path fill="url(#b)" d="M58.1818 14.5193V4.07273C58.1818 1.82342 56.3584 0 54.1091 0H41.0164c-.1925 0-.3851.013964-.576.040727L3.49673 5.3184C1.49004 5.60465 0 7.32334 0 9.34982V25.0228c0 2.2499 1.824 4.0733 4.07389 4.0728l18.53851-.0047c.4375 0 .8721-.0704 1.2869-.2089l31.4979-10.4995c1.6629-.5544 2.7846-2.1108 2.7846-3.8638v.0006Z"/>
|
||||
<path fill="#FF318C" d="m58.1814 15.9476-.0017-11.87545C58.1797 1.82342 56.3562 0 54.1069 0H42.6003c-1.1886 0-2.3185.519564-3.0923 1.42196L6.79872 39.5834c-.63243.7383-.98036 1.6786-.98036 2.6508v11.8755c0 2.2493 1.82342 4.0727 4.07273 4.0727H21.3994c1.1887 0 2.3186-.5196 3.0924-1.422L57.201 18.599c.6331-.7383.9804-1.6786.9804-2.6514Z"/>
|
||||
<path fill="#000" d="M52 12H12v40h40V12Z"/>
|
||||
<path fill="#fff" d="M20.0471 31.161c1.1594.668 2.4537 1.0029 3.8828 1.0029v-.0011c1.2086 0 2.3183-.2241 3.328-.6721 1.0097-.448 1.8486-1.0731 2.5172-1.8771.6754-.8108 1.1274-1.7388 1.3548-2.784h-3.0508c-.1995.54-.4977 1.0172-.896 1.4292-.3915.4057-.864.7188-1.4189.9388-.5543.22-1.1588.3309-1.8131.3309-.8817 0-1.6783-.22-2.3892-.6612-.7114-.4411-1.2697-1.0451-1.6748-1.8131-.3983-.7743-.5972-1.6463-.5972-2.6132 0-.9668.1989-1.8348.5972-2.6028.4057-.7749.964-1.3829 1.6748-1.824.7109-.4412 1.5075-.6612 2.3892-.6612.6537 0 1.2583.1109 1.8131.3309.5549.22 1.0274.5371 1.4189.9491.3983.4057.6965.8789.896 1.4189h3.0508c-.228-1.0451-.6794-1.9691-1.3548-2.7731-.6686-.8109-1.5075-1.44-2.5172-1.888-1.0097-.448-2.1194-.672-3.328-.672-1.4297 0-2.724.3371-3.8828 1.0131-1.1595.668-2.0697 1.5931-2.7309 2.7731-.6611 1.1732-.992 2.4852-.992 3.936 0 1.4509.3309 2.7669.992 3.9469.6617 1.1731 1.572 2.0971 2.7309 2.7731Z"/>
|
||||
<path fill="#fff" d="M36.1248 29.2833V16.9742h-2.9012v14.9331h9.984v-2.624h-7.0828Z"/>
|
||||
<path fill="#fff" d="M16.9941 43.9988h16v3h-16v-3Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.2 KiB |
|
After Width: | Height: | Size: 214 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 263 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 133 KiB |
|
After Width: | Height: | Size: 89 KiB |
|
After Width: | Height: | Size: 97 KiB |
|
After Width: | Height: | Size: 113 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 183 KiB |
|
After Width: | Height: | Size: 139 KiB |
|
After Width: | Height: | Size: 127 KiB |
|
After Width: | Height: | Size: 79 KiB |
@@ -1,39 +1,85 @@
|
||||
#import "../PageTemplate.typ": *
|
||||
#show: page-theme
|
||||
#import "@preview/i-figured:0.2.4"
|
||||
|
||||
= ภาคผนวก
|
||||
#[
|
||||
#show heading: i-figured.reset-counters
|
||||
#show figure: i-figured.show-figure.with(numbering: (..n) => n.at(-1))
|
||||
#show heading.where(level: 2): set heading(numbering: (..nums) => {
|
||||
[ภาคผนวก ]
|
||||
page-numbering(nums.at(-1))
|
||||
linebreak()
|
||||
})
|
||||
#show heading.where(level: 2): set align(center)
|
||||
#counter(heading).update((5, 0))
|
||||
|
||||
== ลิขสิทธิ์เนื้อหาโครงงาน
|
||||
#show: page-theme.with(has-header: false)
|
||||
#[
|
||||
#show heading.where(level: 1): set text(size: 10.5pt, weight: "bold")
|
||||
#v(1fr)
|
||||
= ภาคผนวก
|
||||
#v(1fr)
|
||||
#pagebreak()
|
||||
]
|
||||
|
||||
#i #sym.copyright พ.ศ. 2568 งานนี้อยู่ภายใต้สัญญาอนุญาต Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) หากต้องการดูรายละเอียดเพิ่มเติมเกี่ยวกับสัญญาอนุญาตนี้ โปรดไปที่ https://creativecommons.org/licenses/by-sa/4.0/
|
||||
#include "Budget.typ"
|
||||
#include "UsageGuide.typ"
|
||||
#include "Programs.typ"
|
||||
#include "BlockDiagram.typ"
|
||||
#include "History.typ"
|
||||
|
||||
#i นอกจากที่กล่าวถึงในบรรณานุกรมภาพแล้ว หนังสือโครงงานนี้มีการใช้ไอคอนจาก Visual Studio Code (จาก GitHub repository `microsoft/vscode-codicons`) เวอร์ชัน 0.0.43 และไอคอนจากปลั๊กอิน Dart ใน Visual Studio Code (`Dart-Code/Dart-Code`) เวอร์ชัน 3.124.0 ซึ่งทั้งคู่อยู่ภายใต้ MIT license
|
||||
#pagebreak()
|
||||
#v(1fr)
|
||||
== แผ่นพับคู่มือการใช้งาน
|
||||
#v(1fr)
|
||||
#pagebreak()
|
||||
|
||||
== ลิขสิทธิ์ซอร์สโคดโครงงาน
|
||||
#pagebreak()
|
||||
#v(1fr)
|
||||
== ลิขสิทธิ์โครงงาน
|
||||
#v(1fr)
|
||||
#pagebreak()
|
||||
|
||||
#i เนื่องจากโคดในโครงการนี้เป็นสาธารณะและถูกปกป้องด้วยกฎหมายลิขสิทธิ์
|
||||
โคดนี้จึงมาพร้อมกับสัญญาอนุญาตในการใช้งานโคดสาธารณะทั่วไปของ GNU (GNU Public License) เวอร์ชัน 3
|
||||
#show: page-theme.with(has-header: true)
|
||||
#i #sym.copyright พ.ศ. 2569 เนื้อหาในหนังสือเล่มนี้อยู่ภายใต้สัญญาอนุญาต Creative Commons
|
||||
Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)
|
||||
หากต้องการดูรายละเอียดเพิ่มเติมเกี่ยวกับสัญญาอนุญาตนี้ โปรดไปที่
|
||||
https://creativecommons.org/licenses/by-sa/4.0/
|
||||
|
||||
#i โดยสรุปแล้ว สัญญาอนุญาตนี้มีคุณสมบัติดังนี้ (ไม่ใช่คำแนะนำทางกฎหมาย
|
||||
โปรดอ่านเนื้อหาสัญญาเต็มเพื่อรายละเอียดที่ชัดเจน)
|
||||
#i นอกจากที่กล่าวถึงในบรรณานุกรมภาพแล้ว หนังสือโครงงานนี้มีการใช้ไอคอนจาก Visual Studio
|
||||
Code (จาก GitHub repository `microsoft/vscode-codicons`) เวอร์ชัน 0.0.43
|
||||
และไอคอนจากปลั๊กอิน Dart ใน Visual Studio Code (`Dart-Code/Dart-Code`) เวอร์ชัน
|
||||
3.124.0 ซึ่งทั้งคู่อยู่ภายใต้ MIT license
|
||||
|
||||
การอนุญาต:
|
||||
- อนุญาตการใช้เนื้อหาที่ติดลิขสิทธิ์ในเชิงพาณิชย์
|
||||
- อนุญาตให้สามารถเผยแพร่เนื้อหาที่ติดลิขสิทธ์ได้
|
||||
- อนุญาตให้ดัดแปลงเนื้อหาที่ติดลิขสิทธิ์ได้
|
||||
- ใบอนุญาตนี้ให้สิทธิ์ในการจดสิทธิบัตรจากผู้สนับสนุน
|
||||
- อนุญาตให้ใช้และดัดแปลงเนื้อหาที่ติดลิขสิทธิ์อย่างเป็นส่วนตัวได้
|
||||
#i เนื่องจากโคดในโครงการนี้เป็นสาธารณะและถูกปกป้องด้วยกฎหมายลิขสิทธิ์
|
||||
โคดนี้จึงมาพร้อมกับสัญญาอนุญาตในการใช้งานโคดสาธารณะทั่วไปของ GNU (GNU General Public
|
||||
License)#jb เวอร์ชัน 3
|
||||
|
||||
โดยมีเงื่อนไขว่า:
|
||||
- โคดต้องถูกเปิดเผยหากเนื้อหาที่ติดลิขสิทธิ์ถูกแจกจ่าย
|
||||
- สัญญาอนุญาตต้องถูกรวมกับเนื้อหาที่ติดลิขสิทธิ์ที่ถูกเผยแพร่
|
||||
- การแก้ไขเนื้อหาที่ติดลิขสิทธิ์จะต้องอยู่ภายใต้สัญญาอนุญาตเดียวกัน
|
||||
- หากมีการแก้ไขเนื้อหาที่ติดลิขสัทธิ์ ต้องมีหมายเหตุชัดเจนว่างานนั้นถูกแก้ไขจากงานต้นฉบับ
|
||||
#i โดยสรุปแล้ว สัญญาอนุญาตนี้มีคุณสมบัติดังนี้ (ไม่ใช่คำแนะนำทางกฎหมาย
|
||||
โปรดอ่านเนื้อหาสัญญาเต็มเพื่อรายละเอียดที่ชัดเจน)
|
||||
|
||||
และมีข้อจำกัดว่า:
|
||||
- ผู้ที่เป็นเจ้าของงานไม่มีความรับผิดชอบใด ๆ ทั้งสิ้นหากเกิดความเสียหายต่อการใช้หรือใช้ไม่ได้ของโปรแกรม
|
||||
- โปรแกรมไม่มีการรับประกันใด ๆ ทั้งสิ้น
|
||||
#i การอนุญาต
|
||||
|
||||
สัญญาอนุญาตแบบเต็มที่ถูกบังคับใช้กับโคดในโครงงานนี้มีดังนี้
|
||||
#set enum(indent: 3em)
|
||||
1. อนุญาตการใช้เนื้อหาที่ติดลิขสิทธิ์ในเชิงพาณิชย์
|
||||
2. อนุญาตให้สามารถเผยแพร่เนื้อหาที่ติดลิขสิทธ์ได้
|
||||
3. อนุญาตให้ดัดแปลงเนื้อหาที่ติดลิขสิทธิ์ได้
|
||||
4. ใบอนุญาตนี้ให้สิทธิ์ในการจดสิทธิบัตรจากผู้สนับสนุน
|
||||
5. อนุญาตให้ใช้และดัดแปลงเนื้อหาที่ติดลิขสิทธิ์อย่างเป็นส่วนตัวได้
|
||||
|
||||
#i โดยมีเงื่อนไขว่า
|
||||
|
||||
1. โคดต้องถูกเปิดเผยหากเนื้อหาที่ติดลิขสิทธิ์ถูกแจกจ่าย
|
||||
2. สัญญาอนุญาตต้องถูกรวมกับเนื้อหาที่ติดลิขสิทธิ์ที่ถูกเผยแพร่
|
||||
3. การแก้ไขเนื้อหาที่ติดลิขสิทธิ์จะต้องอยู่ภายใต้สัญญาอนุญาตเดียวกัน
|
||||
4. หากมีการแก้ไขเนื้อหาที่ติดลิขสัทธิ์ ต้องมีหมายเหตุชัดเจนว่างานนั้นถูกแก้ไขจากงานต้นฉบับ
|
||||
|
||||
#i และมีข้อจำกัดว่า
|
||||
|
||||
1. ผู้ที่เป็นเจ้าของงานไม่มีความรับผิดชอบใด ๆ
|
||||
ทั้งสิ้นหากเกิดความเสียหายต่อการใช้หรือใช้ไม่ได้ของโปรแกรม
|
||||
2. โปรแกรมไม่มีการรับประกันใด ๆ ทั้งสิ้น
|
||||
|
||||
สัญญาอนุญาตแบบเต็มที่ถูกบังคับใช้กับโคดในโครงงานนี้มีดังนี้
|
||||
]
|
||||
|
||||
#include "gpl-3.0.typ"
|
||||
|
||||