From 61e7fe16cb5926c9ff2ecdac3ac3619319891294 Mon Sep 17 00:00:00 2001 From: Satakun Utama Date: Wed, 10 Dec 2025 15:56:04 +0700 Subject: [PATCH] Update Chapter 2 contents --- Chapter2/Buzzer.typ | 20 ++ Chapter2/CLanguage.typ | 602 +++++++++++++++++++++++++++++++++-- Chapter2/Chapter2.typ | 10 +- Chapter2/Flutter.typ | 36 +-- Chapter2/HTTP.typ | 15 + Chapter2/HTTPS.typ | 2 - Chapter2/Intro.typ | 14 +- Chapter2/Microcontroller.typ | 102 +++++- Chapter2/NFC.typ | 50 +++ Chapter2/PIR.typ | 2 +- Chapter2/Sensors.typ | 6 + PageTemplate.typ | 1 + References.yaml | 118 ++++++- 13 files changed, 904 insertions(+), 74 deletions(-) create mode 100644 Chapter2/Buzzer.typ create mode 100644 Chapter2/HTTP.typ create mode 100644 Chapter2/Sensors.typ diff --git a/Chapter2/Buzzer.typ b/Chapter2/Buzzer.typ new file mode 100644 index 0000000..0be87a7 --- /dev/null +++ b/Chapter2/Buzzer.typ @@ -0,0 +1,20 @@ +#import "../PageTemplate.typ": i + += ลำโพงสัญญาณ (Buzzer) + +#i Buzzer เป็นอุปกรณ์ส่งสัญญาณเสียงซึ่งอาจเป็น อุปกรณ์ เชิงกลเครื่องกลไฟฟ้าหรือเพียโซอิเล็กทริก (เรียกสั้น ๆ ว่าเพียโซ) การใช้งานทั่วไปของบัซเซอร์และบี๊บเปอร์ ได้แก่อุปกรณ์แจ้งเตือนตัวตั้งเวลาวงจรและการยืนยันการป้อนข้อมูลของผู้ใช้ เช่น การคลิกเมาส์หรือการกดแป้นพิมพ์ + +ประเภทของ Buzzer มี 3 ชนิด คือ + +== ไฟฟ้าเชิงกล (Electromechanical) + +#i อุปกรณ์ในยุคแรกๆ ใช้ระบบไฟฟ้าเครื่องกลแบบเดียวกับกระดิ่งไฟฟ้าโดยไม่มีฆ้องโลหะ ในทำนองเดียวกันรีเลย์อาจเชื่อมต่อเพื่อตัดกระแสไฟฟ้า ที่ทำหน้าที่สั่งการตัวเอง ซึ่งทำให้หน้าสัมผัสส่งเสียงหึ่งๆ (หน้าสัมผัสจะส่งเสียงหึ่งๆ ที่ความถี่สายหากใช้ไฟฟ้ากระแสสลับ) บ่อยครั้งที่อุปกรณ์เหล่านี้ถูกยึดไว้กับผนังหรือเพดานเพื่อใช้เป็นแผงเก็บเสียง คำว่า "buzzer" มาจากเสียงแหบๆ ของ buzzer ระบบไฟฟ้าเครื่องกล + +== กลไก (Mechanical) + +#i จอยบัซเซอร์เป็นตัวอย่างของบัซเซอร์แบบกลไกล้วนๆ และจำเป็นต้องมีไดรเวอร์ ตัวอย่างอื่นๆ ของบัซเซอร์ประเภทนี้คือกริ่งประตู + +== เพียโซอิเล็กทริก (Piezoelectric) + +#i องค์ประกอบเพียโซอิเล็กทริกอาจถูกขับเคลื่อนด้วย วงจรอิเล็กทรอนิกส์ แบบสั่นหรือ แหล่ง สัญญาณเสียง อื่นๆ ซึ่งขับเคลื่อนด้วยเครื่องขยายเสียงเพียโซอิเล็กทริกเสียงที่มักใช้เพื่อระบุว่ามีการกดปุ่ม ได้แก่ เสียงคลิก เสียงกริ่ง หรือเสียงบี๊บ + diff --git a/Chapter2/CLanguage.typ b/Chapter2/CLanguage.typ index 1b620ba..712c024 100644 --- a/Chapter2/CLanguage.typ +++ b/Chapter2/CLanguage.typ @@ -9,51 +9,601 @@ #i แม้ว่าทั้งภาษาซีและไลบรารีมาตรฐานของภาษา ซีจะไม่ได้มีคุณสมบัติยอดนิยมบางอย่างที่พบในภาษาอื่น แต่ก็มีความยืดหยุ่นเพียงพอที่จะรองรับคุณสมบัติเหล่านั้นได้ ตัวอย่างเช่นการวางแนววัตถุและการเก็บขยะนั้นจัดทำโดยไลบรารีภายนอก GLib Object System และ Boehm garbage collector ตามลำดับ -#i ตั้งแต่ปี 2000 เป็นต้นมาภาษาซี ได้รับการจัดอันดับอย่างต่อเนื่องให้อยู่ในอันดับสี่ภาษาสูงสุดในดัชนี TIOBEซึ่งเป็นการวัดความนิยมของภาษาการเขียนโปรแกรม +#i ตั้งแต่ปี 2000 เป็นต้นมาภาษาซี ได้รับการจัดอันดับอย่างต่อเนื่องให้อยู่ในอันดับสี่ภาษาสูงสุดในดัชนี TIOBE ซึ่งเป็นการวัดความนิยมของภาษาการเขียนโปรแกรม -== ตัวอย่าง "Hello, world" +== ตัวอย่าง "hello, world" -#i -ตัวอย่างโปรแกรม "Hello, World!" ที่ปรากฏใน K&R ฉบับพิมพ์ครั้งแรกได้กลายเป็นต้นแบบของโปรแกรมเบื้องต้นในตำราเรียนการเขียนโปรแกรมส่วนใหญ่ โปรแกรมจะพิมพ์ "hello, world" ออกทางเอาต์พุตมาตรฐาน - -เวอร์ชันดั้งเดิมคือ - -```c -main() -{ - printf("hello, world\n"); -} -``` - - -เวอร์ชันที่ทันสมัยกว่าคือ +#i โดยการเรียนภาษาเขียนโปรแกรมใหม่ ๆ ต้องเริ่มด้วยการเขียนโปรแกรมในภาษานั้น ๆ โดยโปรแกรมแรกที่จะเขียนนั้นเหมือน ๆ กันในทุกภาษา คือการพิมพ์ "hello, world" ```c #include -int main(void) +int main() { printf("hello, world\n"); } ``` -#i บรรทัดแรกเป็นคำสั่งพรีโพรเซสเซอร์ ซึ่งระบุด้วย `#include` ซึ่งทำให้พรีโพรเซสเซอร์แทนที่บรรทัดโคดนั้นด้วยข้อความของไฟล์ส่วนหัว `stdio.h` ซึ่งประกอบด้วยการประกาศสำหรับฟังก์ชันอินพุตและเอาต์พุต รวมถึง `printf` โดยวงเล็บเหลี่ยมที่อยู่รอบ ๆ `stdio.h` ระบุว่าสามารถค้นหาไฟล์ส่วนหัวได้โดยใช้กลยุทธ์การค้นหาที่เลือกไฟล์ส่วนหัวที่มาพร้อมกับคอมไพเลอร์ แทนที่จะเป็นไฟล์ที่มีชื่อเดียวกันซึ่งอาจพบได้ในไดเรกทอรีเฉพาะโครงการ +#i คุณสามารถบันทึกไฟล์นี้เป็นไฟล์ที่มีส่วนขยายไฟล์ `.c` เช่น `hello.c` ได้เลย แต่การจะรันโปรแกรมนี้นั้นขึ้นอยู่กับระบบปฏิบัติการของคุณ ตัวอย่างเช่นบนระบบที่มีชุดคอมไพเลอร์ GCC (หรือ MinGW สำหรับเวอร์ชันบน Windows) ติดตั้งอยู่สามารถใช้คำสั่ง -#i บรรทัดโคดถัดไปประกาศฟังก์ชันจุดเข้าสภาพแวดล้อมรันไทม์ `main` เรียกใช้ฟังก์ชันนี้เพื่อเริ่มการทำงานของโปรแกรม ตัวระบุชนิด `int` ระบุว่าฟังก์ชันส่งคืนค่าจำนวนเต็ม รายการพารามิเตอร์ `void` ระบุว่าฟังก์ชันไม่ได้ใช้อาร์กิวเมนต์ใด ๆ สภาพแวดล้อมรันไทม์ส่งอาร์กิวเมนต์สองรายการ (`int` และ `char*[]`) แต่การใช้งานนี้จะละเว้นอาร์กิวเมนต์เหล่านี้ มาตรฐาน ISO C (หัวข้อ 5.1.2.2.1) กำหนดให้ใช้ไวยากรณ์ที่เป็นโมฆะหรืออาร์กิวเมนต์สองรายการนี้ ซึ่งเป็นการปฏิบัติพิเศษที่ฟังก์ชันอื่น ๆ ไม่ได้ให้ +```bash +cc hello.c +``` -#i วงเล็บปีกกาเปิดระบุจุดเริ่มต้นของโคดที่กำหนดฟังก์ชัน +เพื่อคอมไพล์ไฟล์ได้ หากคุณไม่ได้ทำอะไรผิดพลาดไป เช่นการพิมพ์ตกหรือการสะกดผิด การคอมไพล์จะดำเนินการไปอย่างเงียบ ๆ และสร้างไฟล์ไบนารีชื่อ `a.out` ออกมา คุณสามารถรันไฟล์นั้นบนเทอร์มินัลของคุณได้โดยการพิมพ์ `./a.out` แล้วจึงจะได้ข้อความดังต่อไปนี้ออกมา -#i บรรทัดถัดไปของโคดจะเรียกใช้ (เปลี่ยนเส้นทางการทำงานไปยัง) ฟังก์ชันไลบรารีมาตรฐานของ C `printf` พร้อมระบุตำแหน่งอักขระตัวแรกของสตริงที่สิ้นสุดด้วยค่า `null` ที่ระบุเป็นสตริงลิเทอรัลข้อความนี้ `\n` เป็นลำดับ escape ที่แสดง อักขระขึ้นบรรทัด ใหม่ซึ่งเมื่อส่งออกในเทอร์มินัลจะส่งผลให้เคอร์เซอร์เลื่อนไปที่จุดเริ่มต้นของบรรทัดถัดไป แม้ว่า `printf` จะคืนค่า `int` แต่ค่านั้นจะถูกละทิ้งไปอย่างเงียบๆ เครื่องหมายเซมิโคลอน `;` จะสิ้นสุดคำสั่งเรียก +``` +hello, world +``` -#i วงเล็บปีกกาปิดหมายถึงจุดสิ้นสุดของฟังก์ชัน `main` โดยก่อน C99 จำเป็นต้องมีคำสั่ง `return 0;` ที่ชัดเจนเมื่อสิ้นสุดฟังก์ชัน `main` แต่ตั้งแต่ C99 ฟังก์ชัน `main` (ซึ่งเป็นการเรียกใช้ฟังก์ชันเริ่มต้น) จะคืนค่าโดยปริยาย 0 เมื่อถึงวงเล็บปีกกาปิดสุดท้าย +#i โดยโปรแกรมภาษา C นั้น ไม่ว่าจะขนาดใด จะประกอบไปด้วยฟังก์ชันและตัวแปร โดยฟังก์ชันจะประกอบไปด้วยสเตตเมนต์ (statements) ที่ระบุสิ่งที่โปรแกรมจะต้องกระทำ และตัวแปรนั้นกำหนดค่าที่จะถูกใช้งานในการกระทำเหล่านั้น โดยในตัวอย่างมีฟังก์ชันชื่อ `main` ซึ่งปกติแล้วคุณมีอิสระในการตั้งชื่อฟังก์ชันว่าอะไรก็ได้ แต่ฟังก์ชัน `main` นั้นพิเศษ เพราะโปรแกรมของคุณนั้นมีจุดเริ่มต้นที่ `main` ดังนั้น โปรแกรมทุกโปรแกรมต้องมี `main` อยู่สักที่ -== คอนเซปต์พื้นฐาน +#i โดยปกติแล้วฟังก์ชัน `main` นั้นจะเรียกใช้ฟังก์ชันอื่น ๆ เพื่อทำงานให้มัน โดยอาจเป็นฟังก์ชันที่คุณเขียน หรือฟังก์ชันที่มาจากไลบรารีที่คุณใช้งาน ในบรรทัดแรกของโปรแกรมตัวอย่าง -#i โปรแกรมภาษา C เป็นลำดับไฟล์ข้อความ (โดยทั่วไปคือไฟล์ header และไฟล์ source) ที่มีการประกาศต่าง ๆ และไฟล์เหล่านั้นถูกแปลงเป็นโปรแกรมที่ถูกเรียกใช้งานได้ ซึ่งโปรแกรมจะถูกใช้งานเมื่อระบบปฏิบัติการเรียกใช้ฟังก์ชันหลักของโปรแกรม (ยกเว้นหากว่าตัวมันเองคือระบบปฏิบัติการหรือโปรแกรมอิสระ) +```c +#include +``` -#i บางคำศัพท์ในโปรแกรมภาษา C นั้นมีความหมายพิเศษ โดยคำเหล่านั้นคือ#strong[คีย์เวิร์ด] และคำอื่น ๆ สามารถใช้เป็นชื่อ (identifiers) ได้ ซึ่งอาจถูกใช้เป็นชื่อของวัตถุ, ฟังก์ชัน, โครงสร้าง (struct), ยูเนียน, หรือแท็ก enumerations, สมาชิกของมัน, ชื่อ typedef, ฉลาก, หรือมาโคร +มีหน้าที่ในการนำเข้าข้อมูลเกี่ยวกับไลบรารีอินพุต/เอาต์พุตมาตรฐาน โดยบรรทัดนี้นั้นอยู่ในไฟล์ ภาษา C หลายไฟล์ เนื่องจากการแสดงผลข้อมูลนั้นเป็นการกระทำที่ถูกกระทำบ่อย -#i ชื่อของสิ่งต่าง ๆ (ยกเว้นมาโคร) นั้นสามารถใช้ได้แค่ในเพียงในสโคป (scope) ของมัน หมายความว่า หากประกาศตัวแปลไว้ภายในฟังก์ชัน ตัวแปรนั้นจะไม่สามารถใช้นอกสโคปนั้นได้ ซึ่งในกรณีนี้สโคปคือฟังก์ชัน และชื่อบางชื่ออาจมีการลิงก์กันเพื่อให้สโคปอื่น ๆ สามารถลิงก์มาหาชื่อนั้น ๆ ได้ +#i หนึ่งในวิธีการโอนถ่ายข้อมูลระหว่างฟังก์ชันคือการมอบรายการของข้อมูลที่ต้องการมอบให้แก่ฟังก์ชัน โดยค่าที่มอบให้ฟังก์ชันเหล่านั้นมีชื่อเรียกว่า อาร์กิวเมนต์ (arguments) ซึ่งวงเล็บที่ตามหลังชื่อฟังก์ชันนั้นคือวงเล็บที่จะครอบรายการอาร์กิวเมนต์ โดยในตัวอย่างฟังก์ชัน `main` นั้นไม่หวังค่าอาร์กิวเมนต์ใด ๆ สังเกตได้จาก `()` ที่เป็นรายการที่ว่างปล่าว + +#i สเตตเมนต์ที่อยู่ภายในฟังก์ชันนั้นจะถูกครอบด้วยวงเล็บปีกกา `{}` ซึ่งในฟังก์ชัน `main` มีแค่ 1 สเตตเมนต์ คือ + +```c +printf("hello, world\n"); +``` + +#i โดยฟังก์ชันนั้นจะถูกเรียกใช้ได้โดยการเรียกชื่อมัน ตามด้วยรายการอาร์กิวเมนต์ที่ถูกครอบด้วยวงเล็บ ดังนั้น สเตตเมนต์นี้จึงมีการเรียกใช้ฟังก์ชัน `printf` ด้วยอาร์กิวเมนต์ `"hello, world\n"` โดยที่ `printf` เป็นฟังก์ชันจากไลบรารีที่ทำการพรินต์ข้อมูล (ซึ่งการพรินต์ในที่นี้คือการแสดงผลข้อความบนหน้าจอในเทอร์มินัล) และข้อมูลที่มันแสดงนั้นก็คือรายการอักขระที่ถูกครอบอยู่ด้วยเครื่องหมายอัญประกาศนั่นเอง + +#i รายการอักขระที่ถูกครอบด้วยเครื่องหมายอัญประกาศ เช่น `"hello, world\n"` นั้นมีชื่อเรียกว่า character string หรือ string constant และในตัวอย่างนี้นั้น เราจะมีการใช้รายการอักขระนี้เป็นเพียงแค่อาร์กิวเมนต์ของ `printf` และฟังก์ชันอื่น ๆ + +#i ลำดับตัวอักษร `\n` ในสตริงคือสัญกรณ์ภาษา C สำหรับ#emph[ตัวอักษรบรรทัดใหม่] ซึ่งเมื่อถูกพรินต์แล้วจะให้เอาต์พุตไปอยู่ทางด้านซ้ายของบรรทัดใหม่ โดยหากไม่ใส่ `\n` (ซึ่งคุณสามารถทดลองได้เลย) คุณจะพบว่าไม่มีการขึ้นบรรทัดใหม่ของข้อความ และคุณต้องใช้ `\n` ในการขึ้นบรรทัดใหม่ และหากคุณลองทำแบบนี้: + +```c +printf("Hello, world +"); +``` + +คอมไพเลอร์ภาษา C นั้นจะแสดงข้อความแสดงข้อผิดพลาดขึ้นมา + +#i `printf` นั้นจะไม่มีทางใส่ตัวอักษรขึ้นบรรทัดใหม่ให้โดยอัตโนมัติ ดังนั้นคุณสามารถเรียกใช้ฟังก์ชันหลาย ๆ ครั้งเพื่อค่อย ๆ สร้างเอาต์พุตออกมาได้ โดยที่โปรแกรมแรกของเราจะสามารถเขียนแบบนี้ได้ + +```c +#include + +int main() +{ + printf("hello, "); + printf("world"); + printf("\n"); +} +``` + +แล้วข้อความที่แสดงออกมาจะยังคงเดิม + +#i คุณสามารถสังเกตได้ว่า `\n` นั้นจะแทนตัวอักษรตัวเดียว โดยสัญกรณ์ _escape sequence_ เช่น `\n` คือรูปแบบในการเขียนตัวอักษรที่อาจพิมพ์ได้ยากหรือตัวอักษรล่องหน โดยสัญกรณ์อื่น ๆ ในประเภทเดียวกันมีตัวอย่างเช่น `\t` สำหรับตัวอักษรแท็บ, `\b` สำหรับ backspace, `\"` สำหรับการพิมพ์สัญลักษณ์อัญประกาศ (ไม่เช่นนั้นตัวอักษรอัญประกาศจะถูกถือว่าเป็นตัวอักษรในการเริ่มต้น/สิ้นสุดของสตริง), และ `\\` สำหรับการพิมพ์ตัวอักษร backslash เอง + +== ตัวแปร (Variables) + +#i ตัวแปรในภาษา C เบื้องต้นแล้วประกอบไปด้วยประเภทของข้อมูล และชื่อตัวแปร โดยที่ชื่อตัวแปรนั้นสามารถเป็นรายการที่ถูกแบ่งด้วยเครื่องหมายจุลภาคได้ด้วยเช่นกัน ตัวอย่างคือ + +```c +int data; +float a, b, c; +``` + +== ประเภทข้อมูล (Data Types) + +#i ข้อมูลที่เกี่ยวข้องกับตัวเลขมักมีประเภท *unsigned* และ *signed* โดยความแตกต่างหากอธิบายสั้น ๆ คือ + +- *Signed (มีเครื่องหมาย):* ตัวเลขที่สามารถติดลบได้ ระยะข้อมูลตัวอย่างคือ -128 ถึง 127 +- *Unsigned (ไม่มีเครื่องหมาย):* ตัวเลขที่ไม่สามารถติดลบได้ ระยะข้อมูลตัวอย่างคือ 0 ถึง 255 + +#i จะสังเกตได้ว่า ข้อมูลประเภท unsigned นั้นสามารถเก็บตัวเลขบวกได้จำนวนมากกว่า คือสูงสุดที่ 255 แต่หากนำค่าสัมบูรณ์ (absolute value) ของระยะข้อมูลแบบ signed มาบวกกัน เช่น\ #math.equation($|-128| + |127|$, alt: "ค่าสัมบูรณ์ของ -128 บวกค่าสัมบูรณ์ของ 127") จะพบว่าได้ค่า 255 หมายความว่า จริง ๆ แล้วข้อมูลประเภท signed สามารถเก็บข้อมูลได้ 255 ตัวเลขเช่นกัน เพียงแต่ว่าครึ่งหนึ่งของตัวเลขที่สามารถเก็บได้เป็นตัวเลขติดลบ + +*หมายเหตุ:* เลขคณิตจำนวนเต็มมีนิยามแตกต่างกันสำหรับชนิดจำนวนเต็มแบบ signed และ unsigned โปรดดูตัวดำเนินการเลขคณิต โดยเฉพาะอย่างยิ่งการโอเวอร์โฟลว์จำนวนเต็ม + +=== ประเภทบูลีน (Boolean) + +*หมายเหตุ:* ประเภทบูลีนนั้นถูกนำเสนอครั้งแรกในมาตรฐาน C99 + +โดยการกล่าวถึงประเภทข้อมูลบูลีนนั้น ในประวัติของภาษา C แล้วมีสองแบบ + +- `_Bool` (และมีมาโคร `bool`): จนถึงมาตรฐาน C23 +- `bool` (ที่ไม่ใช่แค่มาโคร): มีตั้งแต่มาตรฐาน C23 + +=== ประเภทจำนวนเต็ม (Integer) + +- `short int` (หรืออีกชื่อหนึ่งคือ `short` และสามารถใช้คีย์เวิร์ด `signed` ได้) +- `unsigned short int` (หรือ `unsigned short`) +- `int` (หรือ `signed int`) \ + คือประเภทข้อมูลตัวเลขที่ปกติที่สุด และจะถูกการันตีว่าจะมีขนาดขั้นต่ำ 16 บิตเสมอ โดยระบบทั่วไปส่วนใหญ่ในปัจจุบันจะเป็น 32 บิต +- `unsigned int` (หรือเพียงแค่ `unsigned`): คือประเภท `int` ในแบบ `unsigned`, มี modulo arithmetic, และเหมาะสมสำหรับการเปลี่ยนแปลงบิต +- `long int` (หรือ `long`) +- `unsigned long int` (หรือ `unsigned long`) + +#pagebreak() + +- มีเพิ่มตั้งแต่ C99: + - `long long int` (หรือ `long long`) + - `unsigned long long int` (หรือ `unsigned long long`) +- มีเพิ่มตั้งแต่ C23: + - `_BitInt(n)` (หรือ `signed _BitInt(n)`): ประเภทข้อมูล signed แบบมีขนาดชัดเจน โดย n แทนด้วยจำนวนบิต (รวมถึงบิตเครื่องหมาย และ n จะต้องไม่มากกว่า `BITINT_MAXWIDTH` จากไฟล์ ``) + - `unsigned _BitInt(n)`: เหมือนข้างต้น เพียงแค่เป็นประเภท unsigned (และไม่มีบิตเครื่องหมาย) + +และเหมือนประเภทข้อมูลอื่น ๆ คุณสามารถเรียงคีย์เวิร์ดแบบใดก็ได้ เช่น `unsigned long long int` และ `long int unsigned long` นั้นเหมือนกัน + +ตารางต่อไปนี้สรุปประเภทตัวเลขทั้งหมดและคุณสมบัติของมัน + +#show table.cell.where(y: 1): strong +#show table.cell: set par(justify: false, leading: 0.5em) + +#table( + columns: 7, + align: horizon + center, + table.header( + table.cell([ชื่อประเภท], rowspan: 2), + table.cell([ประเภทเทียบเท่า], rowspan: 2), + table.cell([จำนวนบิตตามรูปแบบข้อมูล], colspan: 5), + [มาตรฐาน C], + [LP32], + [ILP32], + [LLP64], + [LP64], + ), + table.cell(`char`, align: left), + `char`, + table.cell([อย่างน้อย\ *8*], rowspan: 3), + table.cell([*8*], rowspan: 3), + table.cell([*8*], rowspan: 3), + table.cell([*8*], rowspan: 3), + table.cell([*8*], rowspan: 3), + table.cell(`signed char`, align: left), + `signed char`, + table.cell(`unsigned char`, align: left), + `unsigned char`, + + table.cell(`short`, align: left), + table.cell(`short int`, rowspan: 4), + table.cell([อย่างน้อย\ *16*], rowspan: 6), + table.cell([*16*], rowspan: 6), + table.cell([*16*], rowspan: 6), + table.cell([*16*], rowspan: 6), + table.cell([*16*], rowspan: 6), + table.cell(`short int`, align: left), + table.cell(`signed short`, align: left), + table.cell(`signed short int`, align: left), + table.cell(`unsigned short`, align: left), + table.cell([`unsigned`\ `short int`], rowspan: 2), + table.cell(`unsigned short int`, align: left), + + table.cell(`int`, align: left), + table.cell(`int`, rowspan: 3), + table.cell([อย่างน้อย\ *16*], rowspan: 5), + table.cell([*16*], rowspan: 5), + table.cell([*32*], rowspan: 5), + table.cell([*32*], rowspan: 5), + table.cell([*32*], rowspan: 5), + table.cell(`signed`, align: left), + table.cell(`signed int`, align: left), + table.cell(`unsigned`, align: left), + table.cell([`unsigned int`], rowspan: 2), + table.cell(`unsigned int`, align: left), + + table.cell(`long`, align: left), + table.cell(`long int`, rowspan: 4), + table.cell([อย่างน้อย\ *32*], rowspan: 6), + table.cell([*32*], rowspan: 6), + table.cell([*32*], rowspan: 6), + table.cell([*32*], rowspan: 6), + table.cell([*64*], rowspan: 6), + table.cell(`long int`, align: left), + table.cell(`signed long`, align: left), + table.cell(`signed long int`, align: left), + table.cell(`unsigned long`, align: left), + table.cell([`unsigned`\ `long int`], rowspan: 2), + table.cell(`unsigned long int`, align: left), +) + +#pagebreak() + +#table( + columns: 7, + align: horizon + center, + table.header( + table.cell([ชื่อประเภท], rowspan: 2), + table.cell([ประเภทเทียบเท่า], rowspan: 2), + table.cell([จำนวนบิตตามรูปแบบข้อมูล], colspan: 5), + [มาตรฐาน C], + [LP32], + [ILP32], + [LLP64], + [LP64], + ), + table.cell(`long long`, align: left), + table.cell([`long long int` (C99)], rowspan: 4), + table.cell([อย่างน้อย\ *64*], rowspan: 6), + table.cell([*64*], rowspan: 6), + table.cell([*64*], rowspan: 6), + table.cell([*64*], rowspan: 6), + table.cell([*64*], rowspan: 6), + table.cell(`long long int`, align: left), + table.cell(`signed long long`, align: left), + table.cell(`signed long long int`, align: left), + table.cell(`unsigned long long`, align: left), + table.cell([`unsigned long`\ `long int` (C99)], rowspan: 2), + table.cell(`unsigned long long int`, align: left), +) + +และนอกจากค่าบิตขั้นต่ำ มาตรฐาน C นั้นการันตีว่า: + +#i ```c 1``` == ```c sizeof(char)``` #sym.lt.eq ```c sizeof(short)``` #sym.lt.eq ```c sizeof(int)``` #sym.lt.eq ```c sizeof(long)``` #sym.lt.eq ```c sizeof(long long)``` + +*หมายเหตุ:* เงื่อนไขนี้อนุญาตกรณีสุดขีดที่ทุกประเภทมีขนาด 64 บิตและ `sizeof` คืนค่า `1` สำหรับทุกประเภท + +==== รูปแบบข้อมูล (data model) + +#i รูปแบบข้อมูล หรือ data model คือรูปแบบการเก็บข้อมูลของโปรแกรมซึ่งเป็นสิ่งที่กำหนดขนาดของตัวแปร โดยรูปแบบข้อมูลนั้นจะถูกกำหนดโดยแพลตฟอร์มเป้าหมาย ซึ่งมีหน่วยประมวลผลและระบบปฏิบัติการเป็นปัจจัยหลัก โดยตามตารางในหัวข้อก่อนหน้า หลัก ๆ แล้วมีรูปแบบข้อมูลอยู่ 4 รูปแบบ คือ LP32, ILP32, LLP64, และ LP64 ซึ่งหากต้องการหาความหาย L หมายถึง Long, P หมายถึง Pointer, และ I หมายถึง Integer (จำนวนเต็ม) แล้วตามด้วยเลขบิต ดังนั้น สรุปแล้วจึงจะมีความหมายดังนี้ + +ระบบ 32 บิต: +- LP32 หรือ 2/4/4: `long` และ Pointer มีขนาด 32 บิต + - Win16 API +- ILP32 หรือ 4/4/4: `int`, `long`, และ Pointer มีขนาด 32 บิต + - Win32 API + - ระบบ Unix และเสมือน Unix (Linux, Mac OS X) + +ระบบ 64 บิต: +- LLP64 หรือ 4/4/8: `long long` และ Pointer มีขนาด 64 บิต + - Win64 API +- LP64 หรือ 4/8/8: `long` และ Pointer มีขนาด 64 บิต + - ระบบ Unix และเสมือน Unix (Linux, Mac OS X) + +#i รูปแบบอื่น ๆ นั้นหาได้ยาก ตัวอย่างเช่น ILP64 (8/8/8: `int`, `long`, และ Pointer ขนาด 64 บิต) ที่มีการใช้งานแค่ในระบบ Unix 64 บิตช่วงเริ่มต้น (เช่น Unicos บน Cray) + +และโปรดจำไว้ว่า ตัวเลขที่มีขนาดแน่นอนนั้นมีให้ใช้งานใน `` ตั้งแต่ C99 + +=== ประเภทจำนวนทศนิยมจริง (Real floating types) + +ภาษา C นั้นมีประเภทข้อมูลสำหรับแทนตัวเลขทศนิยมจริง 3 (หรือ 6 ตั้งแต่ C23) ประเภท + +- `float`: จำนวนทศนิยมความแม่นยำเดี่ยว ตรงกับฟอร์แมตมาตรฐาน IEEE-754 binary32 หากรองรับ +- `double`: จำนวนทศนิยมความแม่นยำสองเท่า ตรงกับฟอร์แมตมาตรฐาน IEEE-754 binary64 หากรองรับ +- `long double`: จำนวนทศนิยมความแม่นยำเพิ่มเติม ตรงกับฟอร์แมตมาตรฐาน IEEE-754 binary128 หากรองรับ มิฉะนั้นจะตรงกับ IEEE-754 binary64-extended หากรองรับ มิฉะนั้นจะตรงกับรูปแบบจำนวนทศนิยมที่ไม่ตรงกับมาตรฐาน IEEE-754 รูปแบบใดก็ได้ตราบใดที่มีความแม่นยำกว่า binary64 และระยะข้อมูลนั้นอย่างน้อยก็ต้องดีเท่า binary64 และหากไม่รองรับทั้งหมดนั้น จะตรงกับฟอร์แมตมาตรฐาน IEEE-754 binary64 + - รูปแบบ binary128 นั้นถูกใช้โดยระบบ HP-UX, SPARC, MIPS, ARM64, และ z/OS บางระบบ + - รูปแบบ IEEE-754 binary64-extended ที่รู้จักกันอย่างแพร่หลายที่สุดคือรูปแบบความแม่นยำเพิ่มเติม 80 บิต x87 ซึ่งถูกใช้โดยสถาปัตยกรรม x86 และ x86-64 บางระบบ (การยกเว้นที่ควรพูดถึงคือ MSVC ที่กำหนดให้ `long double` อยู่ในรูปแบบเดียวกันกับ `double`, เช่น binary64) + +เมื่อใช้มาตรฐาน C ตั้งแต่ C23 เป็นต้นไปและหากแพลตฟอร์มของคุณใช้งานคอนแสตนต์มาโคร `__STDC_IEC_60559_DFP__` ข้อมูลประเภทตัวเลขทศนิยมดังต่อไปนี้จะถูกรองรับด้วย: + +- `_Decimal32`: แทนรูปแบบมาตรฐาน IEEE-754 decimal32 +- `_Decimal64`: แทนรูปแบบมาตรฐาน IEEE-754 decimal64 +- `_Decimal128`: แทนรูปแบบมาตรฐาน IEEE-754 decimal128 + +มิฉะนั้น ประเภทตัวเลขทศนิยมเพิ่มเติมเหล่านี้จะไม่ถูกรองรับ + +ข้อมูลประเภททศนิยมอาจรองรับค่าพิเศษเพิ่มเติมได้แก่ + +- อนันต์ (Infinity, ทั้งบวกและลบ) +- ศูนย์ติดลบ, `-0.0` โดยมีค่าเท่ากับศูยน์ที่ติดบวก แต่อาจมีความหมายในบางสมการ เช่น `1.0 / 0.0 == INFINITY` แต่ `1.0 / -0.0 == -INFINITY` +- ไม่ใช่ตัวเลข (not-a-number; NaN) ซึ่งไม่เท่ากับอะไรเลย (รวมถึงตัวมันเอง) + +ทศนิยมจำนวนจริงสามารถถูกใช้กับตัวดำเนินการทางคณิตศาสตร์ได้ *+ - / \** และฟังก์ชันทางคณิตศาสตร์จาก `` โดยทั้งตัวดำเนินการและฟังก์ชันจากไลบรารีนั้นสามารถก่อให้เกิดการแสดงข้อผิดพลาดของจำนวนทศนิยมได้และจะตั้งค่า `errno` + +=== ประเภทจำนวนทศนิยมซับซ้อน (Complex floating types) + +#i ประเภทข้อมูลจำนวนทศนิยมซับซ้อนนั้นเป็นประเภทที่แทนตัวเลขเชิงซ้อน (complex number) นั้นคือ ตัวเลขที่สามารถถูกเขียนแทนเป็นผลรวมของจำนวนจริงและจำนวนจริงที่คูณด้วยจำนวนจินตภาพ: #math.equation($a + b i$, alt: "a บวก b i") + +ประเภทจำนวนเชิงซ้อนมีอยู่สามประเภท ได้แก่ + +- ```c float _Complex``` (และสามารถใช้ ```c float complex``` ได้เช่นกันหากนำเข้า ``) +- ```c double _Complex``` (และสามารถใช้ ```c double complex``` ได้เช่นกันหากนำเข้า ``) +- ```c long double _Complex``` (และสามารถใช้ ```c long double complex``` ได้เช่นกันหากนำเข้า ``) + +*หมายเหตุ:* เหมือนกับประเภทอื่น ๆ สามารถพิมพ์คีย์เวิร์ดในลำดับใดก็ได้ ```c long double complex```, ```c complex long double``` และแม้แต่ ```c double complex long``` นั้นคือประเภทข้อมูลเดียวกัน + +=== ประเภทจำนวนทศนิยมจินตภาพ (Imaginary floating types) + +#i ประเภทข้อมูลจำนวนทศนิยมจินตภาพนั้นเป็นประเภทที่แทนตัวเลขจินตภาพ (imaginary number) นั้นคือ ตัวเลขที่สามารถถูกเขียนแทนเป็นจำนวนจริงที่คูณด้วยจำนวนจินตภาพ: #math.equation($b i$, alt: "b i") + +ประเภทจำนวนเชิงซ้อนมีอยู่สามประเภท ได้แก่ + +- ```c float _Imaginary``` (และสามารถใช้ ```c float imaginary``` ได้เช่นกันหากนำเข้า ``) +- ```c double _Imaginary``` (และสามารถใช้ ```c double imaginary``` ได้เช่นกันหากนำเข้า ``) +- ```c long double _Imaginary``` (และสามารถใช้ ```c long double imaginary``` ได้เช่นกันหากนำเข้า ``) + +*หมายเหตุ:* เหมือนกับประเภทอื่น ๆ สามารถพิมพ์คีย์เวิร์ดในลำดับใดก็ได้ ```c long double imaginary```, ```c imaginary long double``` และแม้แต่ ```c double imaginary long``` นั้นคือประเภทข้อมูลเดียวกัน + +=== ประเภทตัวอักษร (Character) + +- `signed char`: ประเภทสำหรับตัวอักษรแบบ signed +- `unsigned char`: ประเภทสำหรับตัวอักษรแบบ unsigned +- `char`: ประเภทสำหรับตัวอักษรแบบไม่ระบุระยะข้อมูล ซึ่งสามารถเท่ากับ `signed char` หรือ `unsigned char` ก็ได้ขึ้นอยู่กับแพลตฟอร์มและคอมไพเลอร์ แต่อย่างไรก็ตาม `char` นั้นไม่ใช่เพียงแค่มาโครที่ลิงก์ไปยังประเภทอื่น ๆ แต่ `char` คือประเภทของมันเอง + +=== คีย์เวิร์ด + +- `bool`, `true`, `false`, `char`, `int`, `short`, `long`, `signed`, `unsigned`, `float`, `double`. +- `_Bool`, `_BitInt`, `_Complex`, `_Imaginary`, `_Decimal32`, `_Decimal64`, `_Decimal128`. + +=== ระยะค่าที่เก็บได้ + +#i ตารางต่อไปนี้ให้ข้อมูลเกี่ยวกับขอบเขตของประเภทข้อมูลต่าง ๆ + +#i ก่อนมาตรฐาน C23 มาตรฐาน C อนุญาตการแทนตัวเลขแบบใดก็ได้ และระยะขั้นต่ำของตัวเลข N บิตคือ #math.equation($-(2^(N-1)-1)$, alt: "ลบ 2 ยกกำลัง N ลบ 1 ทั้งหมดลบ 1") ถึง +#math.equation($+2^(N-1)-1$, alt: "บวก 2 ยกกำลัง N ลบ 1 ทั้งหมดลบ 1") (เช่น *-127* ถึง *127* สำหรับประเภทตัวเลข 8 บิต) ซึ่งตรงกับขอบเขตของส่วนเติมเต็มหนึ่ง (one's complement) หรือการแทนจำนวนมีเครื่องหมาย (sign-and-magnitude) + +#i อย่างไรก็ตาม รูปแบบข้อมูลที่ใช้กันอย่างแพร่หลายทั้งหมด (รวมถึง ILP32, LP32, LP64, และ LLP64) และคอมไพเลอร์ C เกือบทั้งหมดใช้การแทนตัวเลขแบบส่วนเติมเต็มสอง (two's complement) (มีข้อยกเว้นที่ทราบแค่บางคอมไพเลอร์สำหรับระบบ UNISYS) และตั้งแต่มาตรฐาน C23 มันคือการแทนตัวเลขแบบเดียวที่ถูกอนุญาตให้ใช้โดยมาตรฐาน และมีขอบเขตที่แน่นอนระหว่าง +#math.equation($-2^(N-1)$, alt: "ลบ 2 ยกกำลัง N ลบ 1") ถึง +#math.equation($+2^(N-1)-1$, alt: "บวก 2 ยกกำลัง N ลบ 1 ทั้งหมดลบ 1") (เช่น *-128* ถึง *127* สำหรับประเภทตัวเลข 8 บิต) + +(มีการเพิ่มจุลภาคในทศนิยมเพื่อเพิ่มความสะดวกในการอ่าน) + +#show table.cell.where(x: 0): strong +#show math.equation.where(block: true): set block(spacing: 0.6em) +#show math.equation: set text(font: "Noto Sans Math") +#set list(indent: 0em) + +#table( + columns: 5, + align: horizon + center, + table.header( + table.cell([ประเภท], rowspan: 2), + table.cell([ขนาด\ (บิต)], rowspan: 2), + table.cell([รูปแบบ], rowspan: 2), + table.cell([ระยะค่า], colspan: 2), + [โดยประมาณ], [แน่นอน], + ), + table.cell([ตัวอักษร], rowspan: 4), + table.cell([8], rowspan: 2), + [signed], + [], + [*-128* ถึง *127*], + + [unsigned], + [], + [*0* ถึง *255*], + + [16], + [UTF-16], + [], + [*0* ถึง *65535*], + + [32], + [UTF-32], + [], + [*0* ถึง *1114111 (0x10ffff)*], + + table.cell([จำนวน\ เต็ม], rowspan: 6), + table.cell([16], rowspan: 2), + [signed], + [*± 3.27 · 104*], + [*-32768* ถึง *32767*], + + [unsigned], + [*0* ถึง *6.55 · 104*], + [*0* ถึง *65535*], + + table.cell([32], rowspan: 2), + [signed], + [*± 2.14 · 109*], + [*-2,147,483,648* ถึง *2,147,483,647*], + + [unsigned], + [*0* ถึง *4.29 · 109*], + [*0* ถึง *4,294,967,295*], + + table.cell([64], rowspan: 2), + [signed], + [*± 9.22 · 1018*], + [*-9,223,372,036,854,775,808* ถึง *9,223,372,036,854,775,807*], + + [unsigned], + [*0* ถึง *1.84 · 1019*], + [*0* ถึง *18,446,744,073,709,551,615*], + + table.cell([ทศนิยม\ ไบนารี], rowspan: 2), + [32], + [IEEE-754], + table.cell( + [ + - min subnormal: + #math.equation($± 1.401,298,4 · 10^(-45)$, alt: "บวกลบ 1.4012984 คูณ 10 ยกกำลัง -45") + - min normal: + #math.equation($± 1.175,494,3 · 10^(-38)$, alt: "บวกลบ 1.1754943 คูณ 10 ยกกำลัง -38") + - max: \ + #math.equation($± 3.402,823,4 · 10^(38)$, alt: "บวกลบ 3.4028234 คูณ 10 ยกกำลัง 38") + ], + align: left, + ), + table.cell( + [ + - min subnormal:\ + `±0x1p-149` + - min normal:\ + `±0x1p-126` + - max:\ + `±0x1.fffffep+127` + ], + align: left, + ), + + [64], + [IEEE-754], + table.cell( + [ + - min subnormal: + #math.equation($± 4.940,656,458,412\ · 10^(-324)$, alt: "บวกลบ 4.940656458412 คูณ 10 ยกกำลัง ลบ 324", block: true) + - min normal: + #math.equation( + $± 2.225,073,858,507,201,\ 4 · 10^(-308)$, + alt: "บวกลบ 2.2250738585072014 คูณ 10 ยกกำลัง ลบ 308", + block: true, + ) + - max: + #math.equation( + $± 1.797,693,134,862,315,\ 7 · 10^308$, + alt: "บวกลบ 1.7976931348623157 คูณ 10 ยกกำลัง 308", + block: true, + ) + ], + align: left, + ), + table.cell( + [ + - min subnormal: + `±0x1p-1074` + - min normal:\ + `±0x1p-1022` + - max: + `±0x1` \ `.fffffffffffffp+1023` + ], + align: left, + ), +) + +#pagebreak() + +#table( + columns: 5, + align: horizon + center, + table.header( + table.cell([ประเภท], rowspan: 2), + table.cell([ขนาด\ (บิต)], rowspan: 2), + table.cell([รูปแบบ], rowspan: 2), + table.cell([ระยะค่า], colspan: 2), + [โดยประมาณ], [แน่นอน], + ), + + table.cell([ทศนิยม\ ไบนารี], rowspan: 2), + [80], + [x86], + table.cell( + [ + - min subnormal: + #math.equation( + $± 3.645,199,531,882,474,\ 602,528 · 10^(-4951)$, + alt: "บวกลบ 3.645199531882474602528 คูณ 10 ยกกำลัง ลบ 4951", + block: true, + ) + - min normal: + #math.equation( + $± 3.362,103,143,112,093,\ 506,263 · 10^(-4932)$, + alt: "บวกลบ 3.362103143112093506263 คูณ 10 ยกกำลัง ลบ 4932", + block: true, + ) + - max: + #math.equation( + $± 1.189,731,495,357,231,\ 765,021 · 10^(4932)$, + alt: "บวกลบ 1.189731495357231765021 คูณ 10 ยกกำลัง 4932", + block: true, + ) + ], + align: left, + ), + table.cell( + [ + - min subnormal: + `±0x1p-16445` + - min normal: + `±0x1p-16382` + - max: + `±0x1.ffffffff`\ `fffffffep+16383` + ], + align: left, + ), + + [128], + [IEEE-754], + table.cell( + [ + - min subnormal: + #math.equation( + $± 6.475,175,119,438,025,\ 110,924,438,958,227,\ 646,552,5 · 10^(-4966)$, + alt: "บวกลบ 6.4751751194380251109244389582276465525 คูณ 10 ยกกำลัง ลบ 4966", + block: true, + ) + - min normal: + #math.equation( + $± 3.362,103,143,112,093,\ 506,262,677,817,321,\ 752,602,6 · 10^(-4932)$, + alt: "บวกลบ 3.3621031431120935062626778173217526026 คูณ 10 ยกกำลัง ลบ 4932", + block: true, + ) + - max: + #math.equation( + $± 1.189,731,495,357,231,\ 765,085,759,326,628,\ 007,016,2 · 10^4932$, + alt: "บวกลบ 1.1897314953572317650857593266280070162 คูณ 10 ยกกำลัง 4932", + block: true, + ) + ], + align: left, + ), + table.cell( + [ + - min subnormal: + `±0x1p-16494` + - min normal: + `±0x1p-16382` + - max: + `±0x1.ffffffffffffff`\ `ffffffffffffffp+16383` + ], + align: left, + ), + + table.cell([ทศนิยม\ เดซิมอล], rowspan: 3), + [32], + [IEEE-754], + [], + table.cell( + [ + - min subnormal:\ + #math.equation($± 1 · 10^(-101)$, alt: "บวกลบ 1 คูณ 10 ยกกำลัง ลบ 101") + - min normal:\ + #math.equation($± 1 · 10^(-95)$, alt: "บวกลบ 1 คูณ 10 ยกกำลัง ลบ 95") + - max:\ + #math.equation($± 9.999'999 · 10^96$, alt: "บวกลบ 9.999999 คูณ 10 ยกกำลัง 96") + ], + align: left, + ), + + [64], + [IEEE-754], + [], + table.cell( + [ + - min subnormal:\ + #math.equation($± 1 · 10^(-398)$, alt: "บวกลบ 1 คูณ 10 ยกกำลัง ลบ -398") + - min normal:\ + #math.equation($± 1 · 10^(-383)$, alt: "บวกลบ 1 คูณ 10 ยกกำลัง ลบ 383") + - max: + #math.equation( + $± 9.999'999'999'999'999\ · 10^384$, + alt: "บวกลบ 9.999999999999999 คูณ 10 ยกกำลัง 384", + block: true, + ) + ], + align: left, + ), + + [128], + [IEEE-754], + [], + table.cell( + [ + - min subnormal:\ + #math.equation($± 1 · 10^(-6176)$, alt: "บวกลบ 1 คูณ 10 ยกกำลัง ลบ 6176") + - min normal:\ + #math.equation($± 1 · 10^(-6143)$, alt: "บวกลบ 1 คูณ 10 ยกกำลัง ลบ 6143") + - max: + #math.equation( + $ ± 9.999'999'999'999'999'\ 999'999'999'999'999'999\ · 10^6144 $, + alt: "บวกลบ 9.999999999999999999999999999999999 คูณ 10 ยกกำลัง 6144", + block: true, + ) + ], + align: left, + ), +) + +#set list(indent: 1em) == ชุดแปลโปรแกรมของกนู (GNU Compiler Collection; GCC) diff --git a/Chapter2/Chapter2.typ b/Chapter2/Chapter2.typ index 02db201..cfc7bd5 100644 --- a/Chapter2/Chapter2.typ +++ b/Chapter2/Chapter2.typ @@ -1,17 +1,17 @@ -#import "../PageTemplate.typ": chapter-page +#import "../PageTemplate.typ": page-theme #import "@preview/i-figured:0.2.4" -#show: chapter-page +// #show: page-theme #show heading: i-figured.reset-counters.with(level: 3) #show figure: i-figured.show-figure.with(level: 3) -= บทที่ 2 \ ทฤษฎีและเอกสารที่เกี่ยวข้อง - #include "Intro.typ" #set heading(numbering: "1.1", offset: 1) #include "Microcontroller.typ" -#include "PIR.typ" +#include "Sensors.typ" +#include "Buzzer.typ" +#include "HTTP.typ" #include "HTTPS.typ" #include "TLS.typ" #include "NFC.typ" diff --git a/Chapter2/Flutter.typ b/Chapter2/Flutter.typ index 5a943a8..4a740a5 100644 --- a/Chapter2/Flutter.typ +++ b/Chapter2/Flutter.typ @@ -19,8 +19,6 @@ Linux, macOS และ Windows โดย Flutter ได้รับการพ ช่วยลดความยุ่งยากในการรองรับหลายแพลตฟอร์ม เนื่องจากสามารถใช้โคด UI ที่เหมือนกันได้กับทุกแพลตฟอร์มเป้าหมาย -#pagebreak() - == การติดตั้งโปรแกรมเขียนโคด #i จริง ๆ แล้วนั้น Flutter สามารถทำงานกับโปรแกรมเขียนโคดใดก็ได้ แต่มีโปรแกรมเหล่านี้ที่อาจมีประสบการณ์การพัฒนาที่ดีกว่าโปรแกรมอื่น: @@ -78,8 +76,6 @@ winget install --id Git.Git -e --source winget หากต้องการคำสั่งในการติดตั้งแพคเกจเหล่านี้ โปรดดู@flLinuxDetails -#pagebreak() - ==== macOS #i จำเป็นต้องทำการติดตั้งเครื่องมือ command-line Xcode เพื่อเข้าถึงเครื่องมือที่ Flutter จำเป็นต้องใช้ รวมถึง Git @@ -92,6 +88,8 @@ xcode-select --install #i หากคุณไม่ได้ติดตั้งเครื่องมืออยู่แล้ว จะมีไดอะลอกเพื่อคอนเฟิร์มว่าคุณต้องการที่จะติดตั้งมัน กด *Install* และกด *Done* เมื่อทำการติดตั้งเสร็จสิ้นแล้ว +#pagebreak() + === การติดตั้งผ่าน Visual Studio Code 1. เปิด VSCode @@ -119,8 +117,6 @@ xcode-select --install 4. เมื่อเสร็จสิ้น ใช้คำสั่ง `flutter doctor -v` ในเทอร์มินัลที่คุณเลือกเพื่อตรวจสอบการติดตั้ง Flutter ของคุณ \ หากคำสั่งไม่เจอหรือเกิดข้อผิดพลาดขึ้น ตรวจสอบ https://docs.flutter.dev/install/troubleshoot สำหรับข้อมูลเพิ่มเติม -#pagebreak() - === การติดตั้งด้วยตนเอง #i แนะนำให้ทำตาม https://docs.flutter.dev/install/manual#install-flutter เนื่องจากกระบวนการนี้ต้องใช้ข้อมูลที่ใหม่ล่าสุด @@ -145,7 +141,7 @@ Google สามารถใช้พัฒนาแอปพลิเคชั #i หากยังไม่ได้ติดตั้งปลั๊กอิน Flutter โปรดติดตั้งปลั๊กอินก่อน โดยหากอยู่ในหน้าต้อนรับ สามารถติดตั้งปลั๊กอินได้โดยการเข้าไปยังแท็บ *Plugins* หรือหากเปิดโปรเจกต์อื่นอยู่ สามารถเข้าถึงหน้าปลั๊กอินได้โดยการกดที่ไอคอนฟันเฟืองในแถบเครื่องมือ แล้วกด *Plugins...* หลังจากนั้น ในแท็บ *Marketplace* ของหน้าปลั๊กอิน ค้นหา *Flutter* (ผู้ผลิตปลั๊กอินคือ Google) แล้วกด *Install* #afigure( - image("Flutter/homePage.png", width: 60%), + image("Flutter/homePage.png", width: 80%), attr: "ส่วนหนึ่งของโครงงาน, ศตคุณ อุตมะ, ภายใต้ CC BY-SA 4.0", alt: "หน้ายินดีต้อนรับในแท็บ Projects ที่กำลังแสดงรายการโปรเจกต์และปุ่มในการสร้างโปรเจกต์ใหม่", caption: [หน้ายินดีต้อนรับใน Android Studio], @@ -172,8 +168,6 @@ Google สามารถใช้พัฒนาแอปพลิเคชั เมื่อทำการใส่รายละเอียดทั้งหมดแล้ว สามารถกด Create เพื่อสร้างโปรเจกต์ได้เลย -#pagebreak() - == แอพลิเคชันตัวอย่าง เมื่อกดรันแอพลิเคชันด้วยไอคอน #box(image("Flutter/vscode_play.svg", alt: "Play"), baseline: 15%) (หรือ Shift+F10 ใน Android Studio) จะได้แอพลิเคชันดังรูปด้านล่างออกมา @@ -335,8 +329,6 @@ class _MyHomePageState extends State { body: Center( ``` -#pagebreak() - และ `Column` เป็นวิดเจ็ทจัดเลย์เอาต์เช่นกัน มันรับลูกหลายคน (`children`) แล้วจัดเรียงมันในแนวตั้ง โดยค่าเริ่มต้นแล้ว มันจะจัดให้ตัวเองกว้างเท่ากับลูก ๆ ของมัน และพยายามจัดให้ตัวเองสูงเท่าวิดเจ็ทที่สูงกว่า วิดเจ็ทคอลัมน์มีหลายคุณสมบัติในการควบคุมขนาดของมันและการจัดวางลูก ๆ ของมัน โดยด้านล่างมีการใช้อาร์กิวเมนต์ `mainAxisAlignment` ในการจัดลูก ๆ ของมันให้อยู่ตรงกลางในแนวตั้ง โดย "main axis" หรือ แกนหลัก ในกรณีนี้คือแนวตั้ง เพราะคอลัมน์นั้นเป็นแนวตั้ง (และ "cross axis" หรือแกนไขว้ จะเป็นแนวนอน คือแนวตรงข้ามกับแนวหลัก) @@ -505,12 +497,20 @@ flutter: #i ในการพัฒนาแอพลิเคชันสำหรับ Linux ต้องติดตั้งโปรแกรมเพิ่มเติม (build dependencies) ขยายความคือ ด้านบนคือสิ่งที่จำเป็นหากมีระบบอื่นเป็นเป้าหมาย แต่หากต้องการพัฒนาแอพลิเคชัน Linux ต้องติดตั้งโปรแกรมในรายการด้านล่างเพิ่ม -- GTK 3 (ไลบรารีสำหรับการพัฒนา) -- Clang -- CMake -- Ninja -- pkg-config -- ไลบรารี GNU Standard C++ v3 +#grid( + columns: 2, + column-gutter: 1in, + [ + - GTK 3 (ไลบรารีสำหรับการพัฒนา) + - pkg-config + - ไลบรารี GNU Standard C++ v3 + ], + [ + - Clang + - CMake + - Ninja + ], +) #i การติดตั้งไลบรารีและโปรแกรมที่กล่าวไปข้างต้นจะแตกต่างกันไปแต่ละการแจกจ่าย Linux และ Flutter ใช้ไลบรารีพื้นฐานดังกล่าวในการทำงานของแอพลิเคชัน (runtime dependencies) @@ -520,8 +520,6 @@ flutter: แต่โดยทั่วไปแล้ว ไลบรารีเหล่านี้ควรถูกติดตั้งมาอยู่แล้วหากคุณใช้ graphical desktop ทั่วไป -#pagebreak() - ==== Debian ```sh diff --git a/Chapter2/HTTP.typ b/Chapter2/HTTP.typ new file mode 100644 index 0000000..2aa5847 --- /dev/null +++ b/Chapter2/HTTP.typ @@ -0,0 +1,15 @@ +#import "../PageTemplate.typ": i + += เกณฑ์วิธีขนส่งข้อความหลายมิติ (HyperText Transfer Protocol; HTTP) + +#i HTTP (Hypertext Transfer Protocol) เป็น โปรโตคอลชั้นแอปพลิเคชันในชุดโปรโตคอลอินเทอร์เน็ตสำหรับระบบข้อมูลไฮเปอร์มีเดียแบบกระจายและร่วมมือกัน HTTP เป็นรากฐานของการสื่อสารข้อมูลสำหรับ World Wide Web ซึ่งเอกสารไฮเปอร์เท็กซ์ รวมถึง ไฮเปอร์ลิงก์ไปยังทรัพยากรอื่น ๆ ที่ผู้ใช้สามารถเข้าถึงได้อย่างง่ายดาย เช่น โดยการคลิกเมาส์ หรือโดยการแตะหน้าจอในเว็บเบราว์เซอร์ + +#i HTTP เป็น โปรโตคอลแบบคำขอ-การตอบกลับในโมเดลไคลเอนต์-เซิร์ฟเวอร์ ธุรกรรมเริ่มต้นเมื่อไคลเอนต์ส่งคำขอไปยังเซิร์ฟเวอร์ เซิร์ฟเวอร์จะพยายามตอบสนองคำขอและส่งการตอบกลับกลับไปยังไคลเอนต์ ซึ่งอธิบายการจัดการคำขอ และอาจมีทรัพยากรที่ร้องขอ เช่น เอกสาร HTML หรือเนื้อหาอื่น ๆ ก็ได้ + +#i ในสถานการณ์ทั่วไปเว็บเบราว์เซอร์ทำหน้าที่เป็นไคลเอนต์และเว็บเซิร์ฟเวอร์ที่โฮสต์เว็บไซต์หนึ่งเว็บไซต์หรือมากกว่านั้นคือ เซิร์ฟเวอร์ เว็บเบราว์เซอร์เป็นตัวอย่างของตัวแทนผู้ใช้ (UA) ตัวแทนผู้ใช้ประเภทอื่น ๆ ได้แก่ ซอฟต์แวร์จัดทำดัชนีที่ใช้โดยผู้ให้บริการค้นหา (เว็บครอว์เลอร์) เบราว์เซอร์เสียง แอปพลิเคชันมือถือ และซอฟต์แวร์อื่น ๆ ที่เข้าถึง ใช้ หรือแสดงเนื้อหาเว็บ + +#i HTTP ถูกออกแบบมาเพื่ออนุญาตให้องค์ประกอบเครือข่ายตัวกลางสามารถปรับปรุงหรือเปิดใช้งานการสื่อสารระหว่างไคลเอนต์และเซิร์ฟเวอร์ เว็บไซต์ที่มีปริมาณการใช้งานสูงมักได้รับประโยชน์จาก เซิร์ฟเวอร์ แคชเว็บที่ส่งเนื้อหาแทนเซิร์ฟเวอร์ต้นทางเพื่อปรับปรุงเวลาตอบสนอง เว็บเบราว์เซอร์จะแคชทรัพยากรเว็บที่เข้าถึงก่อนหน้านี้และนำกลับมาใช้ซ้ำทุกครั้งที่ทำได้เพื่อลดปริมาณการใช้งานเครือข่ายพร็อกซีเซิร์ฟเวอร์ HTTP ที่ ขอบเขต เครือข่ายส่วนตัวสามารถอำนวยความสะดวกในการสื่อสารสำหรับไคลเอนต์ที่ไม่มีที่อยู่ที่กำหนดเส้นทางได้ทั่วโลก โดยการส่งต่อข้อความไปยังเซิร์ฟเวอร์ภายนอก + +#i เพื่ออนุญาตให้โหนด HTTP ตัวกลาง (พร็อกซีเซิร์ฟเวอร์ แคชเว็บ ฯลฯ) ทำหน้าที่ของตนได้ ส่วนหัว HTTP บางส่วน (พบในคำขอ/การตอบสนอง HTTP) จะได้รับการจัดการแบบฮอปต่อฮอปในขณะที่ส่วนหัว HTTP อื่นๆ จะได้รับการจัดการแบบต้นทางถึงปลายทาง (จัดการโดยไคลเอนต์ต้นทางและเว็บเซิร์ฟเวอร์เป้าหมายเท่านั้น) + +#i ทรัพยากรบนเว็บจะถูกระบุตำแหน่งโดยตัวระบุทรัพยากรแบบสากล (URL) โดยใช้รูปแบบ Uniform Resource Identifier (URI) _http_ และ _https_ โดย URI จะถูกเข้ารหัสเป็นไฮเปอร์ลิงก์ในเอกสาร HTML เพื่อสร้างเอกสารไฮเปอร์เท็กซ์ที่เชื่อมโยงกัน diff --git a/Chapter2/HTTPS.typ b/Chapter2/HTTPS.typ index 48c890a..354e727 100644 --- a/Chapter2/HTTPS.typ +++ b/Chapter2/HTTPS.typ @@ -1,6 +1,4 @@ #import "../PageTemplate.typ": * -#set heading(offset: 1) -#counter(heading).update((2, 3)) = เกณฑ์วิธีขนส่งข้อความหลายมิติแบบมั่นคง (Hypertext Transfer Protocol Secure; HTTPS) diff --git a/Chapter2/Intro.typ b/Chapter2/Intro.typ index c8e293e..42ccfce 100644 --- a/Chapter2/Intro.typ +++ b/Chapter2/Intro.typ @@ -1,10 +1,13 @@ -#import "../PageTemplate.typ": i +#import "../PageTemplate.typ": chapter-page, i +#show: chapter-page #set enum(indent: 3em, numbering: n => "2." + str(n)) += บทที่ 2 \ ทฤษฎีและเอกสารที่เกี่ยวข้อง + #i ผู้จัดทำโครงงาน#h(1em)เครื่องยืนยันตัวตนด้วย NFC#h(1em)ได้ศึกษาทฤษฎีที่เกี่ยวข้องต่าง ๆ และ รวบรวมแนวทางและหลักการต่าง ๆ จากเอกสารงานวิจัยที่เกี่ยวข้องดังต่อไปนี้ + ไมโครคอนโทรเลอร์ (Microcontroller) -+ เซ็นเซอร์อินฟราเรดแบบพาสซีฟ (PIR) ++ เซ็นเซอร์ (Sensors) + ลำโพงสัญญาณ (Buzzer) + เกณฑ์วิธีขนส่งข้อความหลายมิติ (HyperText Transfer Protocol; HTTP) + เกณฑ์วิธีขนส่งข้อความหลายมิติแบบมั่นคง (Hypertext Transfer Protocol Secure; HTTPS) @@ -13,3 +16,10 @@ + Flutter + Git + ภาษาซี (C Programming Language) + +#set heading(numbering: "1.1") +#counter(heading).update((2, 0)) + +== ไมโครคอนโทรเลอร์ (Microcontroller) + +#i ความรู้เกี่ยวกับไมโครคอนโทรลเลอร์เบื้องต้น ไมโครคอนโทรลเลอร์ (มักย่อว่า uC หรือ MCU) คือ อุปกรณ์ควบคุมขนาดเล็ก ซึ่งบรรจุความสามารถที่คล้ายคลึงกับระบบคอมพิวเตอร์ โดยใน ไมโครคอนโทรลเลอร์ได้รวม เอาซีพียูหน่วยความจำและพอร์ต ซึ่งเป็นส่วนประกอบหลักสำคัญของ ระบบคอมพิวเตอร์เข้าไว้ด้วยกัน โดยทำการบรรจุเข้าไว้ในตัวถังเดียวกัน ไมโครคอนโทรลเลอร์ถ้าแปล ความหมายแบบตรงตัวก็คือ ระบบคอนโทรลขนาดเล็กเรียกอีกอย่างหนึ่งคือเป็นระบบคอมพิวเตอร์ ขนาดเล็ก ที่สามารถนำมาประยุกต์ใช้งานได้หลากหลาย โดยผ่านการออกแบบวงจรให้เหมาะกับงาน ต่างๆ และยังสามารถเขียนโปรแกรมคำสั่งเพื่อควบคุมขา Input/Output เพื่อสั่งงานให้ไป ควบคุม อุปกรณ์ต่างๆ ได้อีกด้วย ซึ่งก็นับว่าเป็นระบบที่สามารถนำมาประยุกต์ใช้งานได้หลากหลาย ทั้ง ทางด้าน Digital และ Analog ยกตัวอย่างเช่น ระบบสัญญาณตอบรับอัตโนมัติ, ระบบบัตรคิว, ระบบ ตอกบัตรพนักงาน และอื่นๆ ยิ่งระบบไมโครคอนโทรลเลอร์ในยุคปัจจุบันนั้นสามารถทำการเชื่อต่อกับ ระบบ Network ของคอมพิวเตอร์ทั่วไปได้อีกด้วย ดังนั้นการสั่งงานจึงไม่ใช่แค่หน้าแผงวงจร แต่ อาจจะเป็นการสั่งงานอยู่คนละ ซีกโลกผ่านเครือข่ายอินเตอร์เน็ตก็ได้โครงสร้างโดยทั่วไปของไมโครคอนโทรลเลอร์นั้น สามารถแบ่งออกมาได้เป็น 5 ส่วนใหญ่ๆ ได้แก่ หน่วยประมวลผลกลาง หรือ ซีพียู, หน่วยความจ า, ส่วนติดต่อกับอุปกรณ์ภายนอก หรือพอร์ต, ช่องทางเดินของสัญญาณ หรือบัส และ วงจรกำเนิดสัญญาณนาฬิกา หน่วยความจำนั้น สามารถแบ่งออกเป็น 2 ส่วนคือ หน่วยความจำที่มีไว้สำหรับเก็บ โปรแกรมหลัก เปรียบเสมือนฮาร์ดดิสก์และหน่วยความจำข้อมูล ใช้เป็นเหมือนกับ กระดาษทดในการ คำนวณของซีพียู โดย ESP32 เป็นไมโครคอนโทรลเลอร์แบบ System-on-a-Chip (SoC) ที่มีการรวมส่วนประกอบทั้งหมดที่จำเป็นสำหรับการประมวลผลและการสื่อสารไร้สายไว้ในชิปเดียว ที่มีคุณสมบัติเด่นด้านการ diff --git a/Chapter2/Microcontroller.typ b/Chapter2/Microcontroller.typ index 37f53ac..10aa197 100644 --- a/Chapter2/Microcontroller.typ +++ b/Chapter2/Microcontroller.typ @@ -1,20 +1,112 @@ #import "../PageTemplate.typ": i -#counter(heading).update((2, 0)) -= ไมโครคอนโทรเลอร์ (Microcontroller) +เชื่อมต่อ Wi-Fi และ Bluetooth ในตัว เป็นชิปไมโครคอนโทรลเลอร์แบบ 32 บิต ที่มีความสามารถสูง พัฒนาและผลิตโดย บริษัท Espressif Systems จากประเทศจีน ส่วนประกอบหลักของบอร์ด ESP32 -#i ความรู้เกี่ยวกับไมโครคอนโทรลเลอร์เบื้องต้น ไมโครคอนโทรลเลอร์ (มักย่อว่า uC หรือMCU) คือ อุปกรณ์ควบคุมขนาดเล็ก ซึ่งบรรจุความสามารถที่คล้ายคลึงกับระบบคอมพิวเตอร์ โดยใน ไมโครคอนโทรลเลอร์ได้รวม เอาซีพียูหน่วยความจำและพอร์ต ซึ่งเป็นส่วนประกอบหลักสำคัญของ ระบบคอมพิวเตอร์เข้าไว้ด้วยกัน โดยทำการบรรจุเข้าไว้ในตัวถังเดียวกัน ไมโครคอนโทรลเลอร์ถ้าแปล ความหมายแบบตรงตัวก็คือ ระบบคอนโทรลขนาดเล็กเรียกอีกอย่างหนึ่งคือเป็นระบบคอมพิวเตอร์ ขนาดเล็ก ที่สามารถนำมาประยุกต์ใช้งานได้หลากหลาย โดยผ่านการออกแบบวงจรให้เหมาะกับงาน ต่างๆ และยังสามารถเขียนโปรแกรมคำสั่งเพื่อควบคุมขา Input / Output เพื่อสั่งงานให้ไป ควบคุม อุปกรณ์ต่างๆ ได้อีกด้วย ซึ่งก็นับว่าเป็นระบบที่สามารถนำมาประยุกต์ใช้งานได้หลากหลาย ทั้ง ทางด้าน Digital และ Analog ยกตัวอย่างเช่น ระบบสัญญาณตอบรับอัตโนมัติ, ระบบบัตรคิว, ระบบ ตอกบัตรพนักงาน และอื่นๆ ยิ่งระบบไมโครคอนโทรลเลอร์ในยุคปัจจุบันนั้นสามารถทำการเชื่อต่อกับ ระบบ Network ของคอมพิวเตอร์ทั่วไปได้อีกด้วย ดังนั้นการสั่งงานจึงไม่ใช่แค่หน้าแผงวงจร แต่ อาจจะเป็นการสั่งงานอยู่คนละ ซีกโลกผ่านเครือข่ายอินเตอร์เน็ตก็ได้โครงสร้างโดยทั่วไปของไมโครคอนโทรลเลอร์นั้น สามารถแบ่งออกมาได้เป็น 5 ส่วนใหญ่ๆ ได้แก่ หน่วยประมวลผลกลาง หรือ ซีพียู, หน่วยความจ า, ส่วนติดต่อกับอุปกรณ์ภายนอก หรือพอร์ต, ช่องทางเดินของสัญญาณ หรือบัส และ วงจรกำเนิดสัญญาณนาฬิกา หน่วยความจำนั้น สามารถแบ่งออกเป็น 2 ส่วนคือ หน่วยความจำที่มีไว้สำหรับเก็บ โปรแกรมหลัก เปรียบเสมือนฮาร์ดดิสก์และหน่วยความจำข้อมูล ใช้เป็นเหมือนกับ กระดาษทดในการ คำนวณของซีพียู โดย ESP32 เป็นไมโครคอนโทรลเลอร์แบบ +#i ESP32 คือ ไมโครคอนโทรลเลอร์ราคาประหยัดและประหยัดพลังงานที่ผสานรวมความสามารถทั้งWi-FiและBluetoothชิปเหล่านี้มีตัวเลือกการประมวลผลที่หลากหลาย รวมถึง ไมโครโปรเซสเซอร์ Tensilica Xtensa LX6 ที่มีทั้งแบบดูอัลคอร์และแบบซิงเกิลคอร์ โปรเซสเซอร์ดูอัลคอร์ Xtensa LX7 หรือ ไมโครโปรเซสเซอร์ RISC-V แบบซิงเกิลคอ ร์ นอกจากนี้ ESP32 ยังมีส่วนประกอบที่จำเป็นสำหรับการสื่อสารข้อมูลไร้สาย เช่น สวิตช์เสาอากาศในตัว บาลัน RF เครื่องขยายสัญญาณ ตัวรับสัญญาณเสียงรบกวนต่ำ ตัวกรอง และโมดูลจัดการพลังงาน -#i System-on-a-Chip (SoC) ที่มีการรวมส่วนประกอบทั้งหมดที่จำเป็นสำหรับการประมวลผลและการสื่อสารไร้สายไว้ในชิปเดียว ที่มีคุณสมบัติเด่นด้านการเชื่อมต่อ Wi-Fi และ Bluetooth ในตัว เป็นชิปไมโครคอนโทรลเลอร์แบบ 32 บิต ที่มีความสามารถสูง พัฒนาและผลิตโดย บริษัท Espressif Systems จากประเทศจีน ส่วนประกอบหลักของบอร์ด ESP32 +โดยทั่วไป ESP32 จะถูกฝังอยู่บนแผงวงจรพิมพ์เฉพาะอุปกรณ์ หรือนำเสนอเป็นส่วนหนึ่งของชุดพัฒนาที่มี พินและขั้วต่อ GPIO หลากหลายรูป แบบ โดยมีการกำหนดค่าแตกต่างกันไปตามรุ่นและผู้ผลิต ESP32 ออกแบบโดย Espressif Systems และผลิตโดย TSMC โดยใช้กระบวนการ 40 นาโนเมตรเป็นรุ่นต่อยอดจากไมโครคอนโทรลเลอร์ ESP8266 + +#i นับตั้งแต่เปิดตัว ESP32 รุ่นดั้งเดิม มีการเปิดตัวและประกาศรุ่นต่างๆ มากมาย พวกมันรวมกันเป็นไมโครคอนโทรลเลอร์ตระกูล ESP32 ชิปเหล่านี้มี CPU และความสามารถที่แตกต่างกัน แต่ทั้งหมดใช้ SDK เดียวกันและส่วนใหญ่เข้ากันได้กับโค้ด นอกจากนี้ ESP32 รุ่นดั้งเดิมยังได้รับการปรับปรุง + +#i และส่วนประกอบหลักของบอร์ด 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 == ตารางพาร์ทิชัน (Partition Table) +#i ตารางพาร์ทิชันคือสิ่งที่กำหนดการจัดการรูปแบบหน่วยความจำแฟลชและข้อมูลต่าง ๆ จะถูกเก็บไว้ในแต่ละพาร์ทิชัน โดยผู้พัฒนาสามารถใช้รูปแบบตารางพาร์ทิชันที่ถูกกำหนดมาไว้แล้วหรือสามารถกำหนดรูปแบบตารางพาร์ทิชันเองก็ได้ + +#i โดยตารางพาร์ทัชันที่ถูกใช้ในโครงงานนี้มีรูปแบบดังนี้ + #let partition-table = csv("PartitionTable.csv") #table( columns: 6, - table.header([*Name*], [*Type*], [*SubType*], [*Offset*], [*Size*], [*Flags*]), + table.header([Name], [Type], [SubType], [Offset], [Size], [Flags]), ..partition-table.flatten().slice(6), ) +ซึ่งคือตารางค่าเริ่มต้นของ ESP32 ใน Arduino platform อย่างไรก็ตามมีการเปลี่ยนแปลงระบบเก็บไฟล์จาก SPIFFS เป็น LittleFS โดยที่: + ++ *Name:* ชื่อของพาร์ทิชัน ห้ามซ้ำกัน ชื่อนั้นไม่สำคัญต่อระบบและต้องขนาดไม่เกิน 16 ตัวอักษร (และไม่มีอักขระพิเศษ) ++ *Type:* ประเภทของพาร์ทัชัน สามารถเป็น `data` หรือ `app` ได้ + - `app` คือพาร์ทิชันที่ใช้ในการเก็บแอพลิเคชัน + - `data` คือพาร์ทิชันที่ใช้ในการเก็บข้อมูลทั่วไป ++ *SubType:* ประเภทย่อย ระบุการใช้งานของพาร์ทิชัน `app` และ `data` + - `data` + - `ota`: พาร์ทัชันเก็บข้อมูล OTA (สำหรับการอัพเดททางอากาศ, Over-the-air update) โดยหากไม่ใช้งาน OTA สามารถนำออกได้ โดยขนาดของพาร์ทิชันนี้ควรจะมีขนาดที่แน่นอนอยู่ที่ 8 KiB (0x2000 ไบต์) + - `nvs`: พาร์ทิชันเก็บข้อมูลทั่วไปเช่น ข้อมูล Wi-Fi, ข้อมูลการสอบเทียบ PHY ของอุปกรณ์, และข้อมูลอื่น ๆ ที่ต้องถูกเก็บบนหน่วยความจำถาวร (Non-volatile memory) โดยพาร์ทิชันประเภทนี้เหมาะสมสำหรับการเก็บข้อมูลการตั้งค่าเล็กน้อย ใบรองรับคลาวด์ ฯลฯ และการใช้งาน NVS อีกอย่างคือการเก็บข้อมูลที่ละเอียดอ่อน เนื่องจาก NVS รองรับการเข้ารหัส และเป็นสิ่งที่แนะนำอย่างมากที่จะมีพาร์ทิชัน NVS ขนาดขั้นต่ำ 12 KiB (0x3000 ไบต์) และหากจำเป็น คุณสามารถขยายขนาดเพิ่มได้ โดยขนาดที่แนะนำนั้นอยู่ระหว่าง 12 KiB และ 64 KiB ถึงแม้ว่าคุณจะสามารถขยายให้มันใหญ่กว่านี้ได้ การใช้งานระบบไฟล์เช่น FAT หรือ SPIFFS นั้นจะเหมาะสมสำหรับข้อมูลที่ใหญ่กว่า + - `coredump`: ประเภทพาร์ทิชันย่อยนี้มีหน้าที่ในการเก็บข้อมูล core dump บนหน่วยความจำแฟลช โดย core dump นั้นคือข้อมูลที่ถูกใช้งานสำหรับการตรวจสอบข้อผิดพลาดร้ายแรงเช่นการแครชและแพนิค โดยฟังก์ชันนี้จะต้องถูกเปิดในการตั้งค่าโปรเจกต์และตั้งที่หมายในการแฟลช และพาร์ทิชันนี้มีขนาดที่แนะนำอยู่ที่ 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 นั้นจำเป็นต้องใช้พาร์ทิชัน 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:* ในปัจจุบันคอลัมน์นี้ใช้เพียงแค่เพื่อบ่งบอกว่าพาร์ทิชันนั้น ๆ ถูกเข้ารหัสหรือไม่ + == LittleFS +#i LittleFS คือระบบไฟล์ขนาดเล็กที่ปลอดภัยต่อความล้มเหลวที่ออกแบบมาสำหรับไมโครคอนโทรลเลอร์ + +#show raw: set par(leading: 0.5em) + +``` + | | | .---._____ + .-----. | | +--|o |---| littlefs | +--| |---| | + '-----' '----------' + | | | +``` + +*ความยืดหยุ่นในการป้องกันการสูญเสียพลังงาน* littlefs ออกแบบมาเพื่อรับมือกับปัญหาไฟฟ้าดับแบบสุ่ม การดำเนินการไฟล์ทั้งหมดมีการรับประกันการคัดลอกข้อมูลเมื่อเขียนข้อมูล (copy-on-write) ที่แข็งแกร่ง และหากไฟฟ้าดับ ระบบไฟล์จะกลับสู่สถานะปกติล่าสุดที่ทราบ + +*การปรับระดับการสึกหรอแบบไดนามิก* littlefs ออกแบบมาเพื่อแฟลชโดยเฉพาะ และมอบการปรับระดับการสึกหรอบนบล็อกแบบไดนามิก นอกจากนี้ littlefs ยังสามารถตรวจจับบล็อกเสียและแก้ไขปัญหาได้ + +*RAM/ROM แบบมีขอบเขต* ittlefs ออกแบบมาเพื่อทำงานกับหน่วยความจำขนาดเล็ก การใช้งาน RAM ถูกจำกัดอย่างเข้มงวด ซึ่งหมายความว่าการใช้ RAM จะไม่เปลี่ยนแปลงเมื่อระบบไฟล์เติบโตขึ้น ระบบไฟล์ไม่มีการเรียกซ้ำแบบไม่มีขอบเขต และหน่วยความจำแบบไดนามิกถูกจำกัดให้อยู่ในบัฟเฟอร์ที่กำหนดค่าได้ซึ่งสามารถจัดเตรียมแบบคงที่ได้ + +== ออกแบบ + +#i ในระดับสูง littlefs เป็นระบบไฟล์แบบบล็อกที่ใช้ไฟล์บันทึกขนาดเล็กในการจัดเก็บข้อมูลเมตาและโครงสร้าง copy-on-write (COW) ขนาดใหญ่ในการจัดเก็บข้อมูลไฟล์ + +#i ใน littlefs ส่วนผสมเหล่านี้ก่อตัวเป็นเค้กสองชั้น โดยที่ท่อนไม้ขนาดเล็ก (เรียกว่าคู่เมตาเดตา) จะให้การอัปเดตเมตาเดตาอย่างรวดเร็วในทุกที่ในที่เก็บข้อมูล ในขณะที่โครงสร้าง COW จะจัดเก็บข้อมูลไฟล์อย่างกะทัดรัดและไม่มีค่าใช้จ่ายในการขยายการสึกหรอใดๆ + +#i โครงสร้างข้อมูลทั้งสองนี้สร้างขึ้นจากบล็อก ซึ่งถูกป้อนโดยตัวจัดสรรบล็อกร่วม โดยการจำกัดจำนวนการลบข้อมูลที่อนุญาตบนบล็อกต่อการจัดสรรแต่ละครั้ง ตัวจัดสรรจะปรับระดับการสึกหรอแบบไดนามิกทั่วทั้งระบบไฟล์ + +``` + root + .--------.--------. + | A'| B'| | + | | |-> | + | | | | + '--------'--------' + .----' '--------------. + A v B v + .--------.--------. .--------.--------. + | C'| D'| | | E'|new| | + | | |-> | | | E'|-> | + | | | | | | | | + '--------'--------' '--------'--------' + .-' '--. | '------------------. + v v .-' v +.--------. .--------. v .--------. +| C | | D | .--------. write | new E | +| | | | | E | ==> | | +| | | | | | | | +'--------' '--------' | | '--------' + '--------' .-' | + .-' '-. .-------------|------' + v v v v + .--------. .--------. .--------. + | F | | G | | new F | + | | | | | | + | | | | | | + '--------' '--------' '--------' +``` diff --git a/Chapter2/NFC.typ b/Chapter2/NFC.typ index dd120cd..789967c 100644 --- a/Chapter2/NFC.typ +++ b/Chapter2/NFC.typ @@ -1,3 +1,53 @@ #import "../PageTemplate.typ": * = การสื่อสารสนามใกล้ (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 กิโลบิต/วินาที + +#i ฟอรัม 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 แทนที่เทคโนโลยีที่เป็นกรรมสิทธิ์ที่ใช้ในระบบก่อนหน้านี้ + +#i โปรแกรมอนุญาตสิทธิ์สิทธิบัตรสำหรับ NFC กำลังอยู่ระหว่างการใช้งานโดย France Brevets ซึ่งเป็นกองทุนสิทธิบัตรที่จัดตั้งขึ้นในปี 2011 โปรแกรมนี้อยู่ระหว่างการพัฒนาโดย Via Licensing Corporation ซึ่งเป็นบริษัทสาขาอิสระของ Dolby Laboratories และยุติลงในเดือนพฤษภาคม 2012 ไลบรารี NFC แบบโอเพนซอร์สและอิสระต่อแพลตฟอร์ม libnfc มีให้บริการภายใต้ใบอนุญาตสาธารณะทั่วไปแบบผ่อนปรนของ GNU + +#i แอปพลิเคชันปัจจุบันและที่คาดว่าจะมีในอนาคต ได้แก่ ธุรกรรมแบบไร้สัมผัส การแลกเปลี่ยนข้อมูล และการตั้งค่าการสื่อสารที่ซับซ้อนมากขึ้น เช่น 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 สามารถทำได้หากอุปกรณ์ทั้งสองมีพลังงาน + +#i แท็ก NFC มีข้อมูลและโดยทั่วไปเป็นแบบอ่านอย่างเดียว แต่อาจเขียนได้ ผู้ผลิตสามารถกำหนดรหัสเองได้ หรือใช้ข้อกำหนดของ NFC Forum แท็กสามารถจัดเก็บข้อมูลส่วนบุคคลอย่างปลอดภัย เช่น ข้อมูลบัตรเดบิตและบัตรเครดิต ข้อมูลโปรแกรมสะสมคะแนน รหัส PIN และรายชื่อผู้ติดต่อในเครือข่าย +รวมถึงข้อมูลอื่นๆ NFC Forum กำหนดแท็กห้าประเภทที่มีความเร็วและความสามารถในการสื่อสารที่แตกต่างกันในแง่ของความสามารถในการกำหนดค่าหน่วยความจำ ความปลอดภัยการเก็บข้อมูลและความทนทานต่อการเขียน + +#i เช่นเดียวกับ เทคโนโลยี การ์ดแบบ 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$) นิ้ว) โปรดทราบว่าเนื่องจากเสาอากาศรับสัญญาณอาจถูกดับในกระแสวนโดยพื้นผิวโลหะที่อยู่ใกล้เคียง แท็กอาจต้องแยกออกจากพื้นผิวดังกล่าวอย่างน้อยที่สุด + +มาตรฐาน ISO/IEC 18092 รองรับอัตราข้อมูล 106, 212 หรือ 424 กิโลบิต/วินาที + +การสื่อสารเกิดขึ้นระหว่างอุปกรณ์ "ตัวเริ่มต้น" ที่ใช้งานอยู่และอุปกรณ์เป้าหมาย ซึ่งอาจเป็น: + +/ พาสซีฟ: อุปกรณ์ตัวเริ่มต้นจะทำหน้าที่เป็นสนามแม่เหล็กพาหะ และอุปกรณ์เป้าหมายจะสื่อสารโดยการปรับสนามแม่เหล็กตกกระทบ ในโหมดนี้ อุปกรณ์เป้าหมายอาจดึงพลังงานจากสนามแม่เหล็กที่ตัวเริ่มต้นจัดหาให้ + +/ คล่องแคล่ว: ทั้งอุปกรณ์เริ่มต้นและอุปกรณ์เป้าหมายสื่อสารกันโดยการสร้างฟิลด์ของตัวเองสลับกัน อุปกรณ์จะหยุดส่งสัญญาณเพื่อรับข้อมูลจากอีกอุปกรณ์หนึ่ง โหมดนี้กำหนดให้อุปกรณ์ทั้งสองต้องมีแหล่งจ่ายไฟ + +#table( + columns: 3, + table.header([ความเร็ว (กิโลบิต/วินาที)], [อุปกรณ์ที่ใช้งานอยู่], [อุปกรณ์แบบพาสซีฟ]), + [424], [แมนเชสเตอร์ 10% ASK], [แมนเชสเตอร์ 10% ASK], + [212], [แมนเชสเตอร์ 10% ASK], [แมนเชสเตอร์ 10% ASK], + [106], [มิลเลอร์ดัดแปลง ถามได้ 100%], [แมนเชสเตอร์ 10% ASK], +) + +#i NFC ใช้การเข้ารหัสสองแบบที่แตกต่างกันในการถ่ายโอนข้อมูล หากอุปกรณ์ที่ใช้งานอยู่ถ่ายโอนข้อมูลที่ความเร็ว 106 กิโลบิต/วินาที จะใช้การเข้ารหัสแบบมิลเลอร์ที่ปรับเปลี่ยนแล้วพร้อมการมอดูเลต 100 เปอร์เซ็นต์ในกรณีอื่นๆทั้งหมดจะใช้การเข้ารหัสแบบแมนเชสเตอร์โดยมีอัตราการมอดูเลต 10 เปอร์เซ็นต์ + +อุปกรณ์ NFC ที่ใช้งานอยู่ทุกเครื่องสามารถทำงานในโหมดใดโหมดหนึ่งหรือหลายโหมดได้: + +/ การจำลองการ์ด NFC: ช่วยให้อุปกรณ์ที่รองรับ NFC เช่น สมาร์ทโฟน ทำหน้าที่เหมือนสมาร์ทการ์ด ช่วยให้ผู้ใช้ทำธุรกรรมต่างๆ เช่น การชำระเงินหรือการออกตั๋วได้ ดูการจำลองการ์ดโฮสต์ +/ เครื่องอ่าน/เขียน NFC: ช่วยให้อุปกรณ์ที่เปิดใช้งาน NFC สามารถอ่านข้อมูลที่จัดเก็บไว้ในแท็ก NFC ราคาไม่แพงที่ฝังอยู่ในฉลากหรือโปสเตอร์อัจฉริยะได้ +/ NFC เพียร์ทูเพียร์: ช่วยให้อุปกรณ์ที่เปิดใช้งาน NFC สองเครื่องสามารถสื่อสารกันเพื่อแลกเปลี่ยนข้อมูลในลักษณะ เฉพาะกิจ + +แท็ก NFC คือหน่วยเก็บข้อมูลแบบพาสซีฟที่อุปกรณ์ NFC สามารถอ่านและเขียนข้อมูลได้ในบางกรณี โดยทั่วไปจะมีข้อมูล (ณ ปี 2015 มีขนาดระหว่าง 96 ถึง 8,192 ไบต์) และเป็นแบบอ่านอย่างเดียวในการใช้งานปกติ แต่อาจเขียนซ้ำได้ การใช้งานรวมถึงการจัดเก็บข้อมูลส่วนบุคคลที่ปลอดภัย (เช่นข้อมูล บัตร เดบิตหรือบัตรเครดิตข้อมูลโปรแกรมสะสมคะแนน หมายเลขประจำตัว (PIN) และรายชื่อผู้ติดต่อ) แท็ก NFC สามารถเข้ารหัสแบบกำหนดเองโดยผู้ผลิต หรือใช้ข้อกำหนดเฉพาะของอุตสาหกรรม diff --git a/Chapter2/PIR.typ b/Chapter2/PIR.typ index ec80cfc..63fadc7 100644 --- a/Chapter2/PIR.typ +++ b/Chapter2/PIR.typ @@ -1,5 +1,5 @@ #import "../PageTemplate.typ": * -#set heading(offset: 1) +#set heading(offset: 2) #let image-height = 2.5in diff --git a/Chapter2/Sensors.typ b/Chapter2/Sensors.typ new file mode 100644 index 0000000..f0fee55 --- /dev/null +++ b/Chapter2/Sensors.typ @@ -0,0 +1,6 @@ +#import "../PageTemplate.typ": * +#set heading(offset: 1) + += เซนเซอร์ (Sensors) + +#include "PIR.typ" diff --git a/PageTemplate.typ b/PageTemplate.typ index c235b8f..46c09f7 100644 --- a/PageTemplate.typ +++ b/PageTemplate.typ @@ -57,6 +57,7 @@ show heading.where(level: 1): set align(center) show heading.where(level: 2): set text(size: 12pt) show raw: set text(font: "Cascadia Code", size: 10pt) + show table.cell.where(y: 0): strong set ref(supplement: "หัวข้อ") doc } diff --git a/References.yaml b/References.yaml index 4daa1c0..202501e 100644 --- a/References.yaml +++ b/References.yaml @@ -5,6 +5,7 @@ wkNodeMcu: language: en publisher: มูลนิธิวิกิมีเดีย (ภายใต้ CC BY-SA 4.0) url: + date: 2025-12-8 value: https://en.wikipedia.org/w/index.php?title=NodeMCU&oldid=1306030712 wkEsp32: @@ -14,6 +15,7 @@ wkEsp32: 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 wkEspressif: @@ -23,6 +25,7 @@ wkEspressif: 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 wkFlutter: @@ -101,7 +104,9 @@ wkDart: date: 2025-11-21 language: en publisher: มูลนิธิวิกิมีเดีย (ภายใต้ CC BY-SA 4.0) - url: https://en.wikipedia.org/w/index.php?title=Dart_(programming_language)&oldid=1323401675 + url: + date: 2025-12-8 + value: https://en.wikipedia.org/w/index.php?title=Dart_(programming_language)&oldid=1323401675 wkX509: type: Web @@ -109,7 +114,9 @@ wkX509: date: 2025-11-11 language: en publisher: มูลนิธิวิกิมีเดีย (ภายใต้ CC BY-SA 4.0) - url: https://en.wikipedia.org/w/index.php?title=X.509&oldid=1321610537 + url: + date: 2025-11-29 + value: https://en.wikipedia.org/w/index.php?title=X.509&oldid=1321610537 wkDerEncoding: type: Web @@ -117,7 +124,9 @@ wkDerEncoding: language: en publisher: มูลนิธิวิกิมีเดีย (ภายใต้ CC BY-SA 4.0) date: 2025-10-6 - url: https://en.wikipedia.org/w/index.php?title=X.690&oldid=1315457524#DER_encoding + url: + date: 2025-12-3 + value: https://en.wikipedia.org/w/index.php?title=X.690&oldid=1315457524#DER_encoding wkOpenSSL: type: Web @@ -125,7 +134,9 @@ wkOpenSSL: date: 2025-12-1 language: en publisher: มูลนิธิวิกิมีเดีย (ภายใต้ CC BY-SA 4.0) - url: https://en.wikipedia.org/w/index.php?title=OpenSSL&oldid=1325138239 + url: + date: 2025-12-3 + value: https://en.wikipedia.org/w/index.php?title=OpenSSL&oldid=1325138239 wkMaterial: type: Web @@ -133,7 +144,19 @@ wkMaterial: date: 2025-11-15 language: en publisher: มูลนิธิวิกิมีเดีย (ภายใต้ CC BY-SA 4.0) - url: https://en.wikipedia.org/w/index.php?title=Material_Design&oldid=1322252287 + url: + date: 2025-12-6 + value: https://en.wikipedia.org/w/index.php?title=Material_Design&oldid=1322252287 + +wkBuzzer: + type: Web + title: Buzzer + date: 2025-11-13 + language: en + publisher: มูลนิธิวิกิมีเดีย (ภายใต้ CC BY-SA 4.0) + url: + date: 2025-12-10 + value: https://en.wikipedia.org/w/index.php?title=Buzzer&oldid=1321902450 androidJdkVersion: type: Web @@ -157,13 +180,25 @@ sofFlutterMinSdk: date: 2025-11-26 value: https://stackoverflow.com/a/79746636 +sofCDataModel: + type: Web + title: Are data models - ILP32 or LP64 decided by OS or the Hardware Architecture? + date: 2020-10-14 + language: en + publisher: Stackoverflow (ภายใต้ CC BY-SA 4.0) + url: + date: 2025-12-9 + value: https://stackoverflow.com/a/79746636 + flInstallManually: type: Web title: Install Flutter manually date: 2025-10-28 language: en publisher: Flutter (ภายใต้ CC BY 3.0 และ BSD License) - url: https://docs.flutter.dev/install/manual + url: + date: 2025-12-6 + value: https://docs.flutter.dev/install/manual flVsCode: type: Web @@ -171,7 +206,9 @@ flVsCode: date: 2025-10-28 language: en publisher: Flutter (ภายใต้ CC BY 3.0 และ BSD License) - url: https://docs.flutter.dev/install/with-vs-code + url: + date: 2025-12-6 + value: https://docs.flutter.dev/install/with-vs-code flLinuxDev: type: Web @@ -179,7 +216,9 @@ flLinuxDev: date: 2025-9-25 language: en publisher: Flutter (ภายใต้ CC BY 3.0 และ BSD License) - url: https://docs.flutter.dev/platform-integration/linux/setup + url: + date: 2025-12-6 + value: https://docs.flutter.dev/platform-integration/linux/setup flLinuxBuild: type: Web @@ -187,39 +226,90 @@ flLinuxBuild: date: 2025-9-5 language: en publisher: Flutter (ภายใต้ CC BY 3.0 และ BSD License) - url: https://docs.flutter.dev/platform-integration/linux/building + url: + date: 2025-12-6 + value: https://docs.flutter.dev/platform-integration/linux/building archPkgs: type: Web title: Arch Linux - Package Search date: 2025-12-1 language: en - url: https://archlinux.org/packages/ + url: + date: 2025-12-1 + value: https://archlinux.org/packages/ fedoraPkgs: type: Web title: Fedora Packages date: 2025-12-1 language: en - url: https://packages.fedoraproject.org/ + url: + date: 2025-12-1 + value: https://packages.fedoraproject.org/ debianPkgs: type: Web title: Debian -- Packages date: 2025-12-1 language: en - url: https://www.debian.org/distrib/packages + url: + date: 2025-12-1 + value: https://www.debian.org/distrib/packages gitWindows: type: Web title: Git - Install for Windows date: 2025-11-30 language: en - url: https://git-scm.com/install/windows + url: + date: 2025-12-1 + value: https://git-scm.com/install/windows twMaterialYou: type: Post title: "The latest in Material Design is NOW available" date: 2021-10-28 author: Material Design [@materialdesign] - url: https://x.com/materialdesign/status/1453409331697885192 + url: + date: 2025-12-1 + value: https://x.com/materialdesign/status/1453409331697885192 + +cpprefCBasics: + type: Web + title: Declarations + date: 2025-02-09 + publisher: cppreference.com (ภายใต้ CC BY-SA 3.0 Unported) + url: + date: 2025-12-08 + value: https://cppreference.com/w/c/language/declarations.html + +cpprefATypes: + type: Web + title: Arithmetic types + date: 2025-02-09 + publisher: cppreference.com (ภายใต้ CC BY-SA 3.0 Unported) + url: + date: 2025-12-09 + value: https://cppreference.com/w/c/language/arithmetic_types.html + +ansiC: + type: Book + title: The ANSI C Programming Language + page-total: 238 + author: + - Brian W. Kernighan + - Dennis M. Ritchie + publisher: Prentice Hall + 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 + +ghEsp32Partition: + type: Web + title: default.csv + date: 2024-4-15 + url: + date: 2025-12-9 + value: https://github.com/espressif/arduino-esp32/blob/2ede5ac10923afd1e3a42ce1fb41930a9de05d16/tools/partitions/default.csv