สารบัญ:
- ขั้นตอนที่ 1: ข้อควรพิจารณาในการออกแบบรูปภาพขนาดใหญ่
- ขั้นตอนที่ 2: โปรโตคอลสัญญาณ: ภาษาง่าย ๆ สำหรับการสื่อสารผ่านเครือข่าย
- ขั้นตอนที่ 3: เราต้องการควบคุมการทำงานของอุปกรณ์ตามสถานะปัจจุบัน
- ขั้นตอนที่ 4: เราต้องการตอบสนองต่อการป้อนข้อมูลของผู้ใช้
- ขั้นตอนที่ 5: เราต้องการเริ่มต้นค่าข้อมูลในหน่วยความจำของอุปกรณ์เมื่ออุปกรณ์บูทขึ้น
- ขั้นตอนที่ 6: เราต้องการแสดงภาพเคลื่อนไหวและกราฟิกโดยใช้จอแสดงผล LED 5 X 5
- ขั้นตอนที่ 7: เราต้องการส่งข้อมูลแบบไร้สายโดยใช้วิทยุของอุปกรณ์
- ขั้นตอนที่ 8: เราต้องการฟังและรับข้อมูลผ่านวิทยุของอุปกรณ์และประมวลผลตามนั้น
- ขั้นตอนที่ 9: อุปกรณ์รูท: เราต้องการให้เลือกสัญญาณ
- ขั้นตอนที่ 10: เราเสร็จแล้ว
วีดีโอ: Network Rivalry: เกมที่มีความหน่วงต่ำสำหรับ BBC Micro:bit: 10 ขั้นตอน (พร้อมรูปภาพ)
2024 ผู้เขียน: John Day | [email protected]. แก้ไขล่าสุด: 2024-01-30 13:05
ในบทช่วยสอนนี้ ฉันจะอธิบายวิธีใช้งานเกมมัลติเพลเยอร์พื้นฐานบน BBC micro:bit ด้วยคุณสมบัติดังต่อไปนี้:
- อินเทอร์เฟซที่เรียบง่าย
- ความหน่วงต่ำระหว่างการกดปุ่มและการอัพเดตหน้าจอ
- จำนวนผู้เข้าร่วมที่ยืดหยุ่น
- ควบคุมเกมได้ง่ายโดยใช้อุปกรณ์รีโมทหลัก ("รูท")
เกมดังกล่าวเป็นการจำลองการเมืองเป็นหลัก ผู้เล่นทุกคนเริ่มออกโดยไม่ได้มอบหมายให้ทีมใดก็ได้ ยกเว้นผู้เล่นสองคน หนึ่งในผู้เล่นเหล่านี้ได้รับมอบหมายให้อยู่ในทีม A และอีกคนหนึ่งได้รับมอบหมายให้อยู่ในทีม B
วัตถุประสงค์ของเกมให้ผู้เล่นแต่ละคนอยู่ในทีมกับผู้เล่นส่วนใหญ่ในเวลาที่ทุกคนเปลี่ยนใจ
แผนภาพด้านบนแสดงเครื่องจักรที่มีสถานะจำกัด กล่าวคือ ข้อมูลจำเพาะของสถานะที่อุปกรณ์สามารถอยู่ได้และการเปลี่ยนแปลงระหว่างสถานะเหล่านั้น
สถานะถือได้ว่าเป็นชุดข้อมูลปัจจุบันที่อธิบายหน่วยความจำของอุปกรณ์ตั้งแต่เปิดเครื่อง จากข้อมูลดังกล่าว อุปกรณ์อาจดำเนินการบางอย่างหรือตอบสนองต่อข้อมูลที่ผู้ใช้ป้อนแตกต่างกัน
การเปลี่ยนภาพเป็นเงื่อนไขเชิงตรรกะที่ทำให้อุปกรณ์เปลี่ยนสถานะเมื่อเป็นจริง การเปลี่ยนจากสถานะหนึ่งไปอีกสถานะหนึ่งได้ รัฐอาจมีการเปลี่ยนหลายครั้ง
แผนภาพด้านบนระบุสถานะต่อไปนี้:
- ยังไม่ได้มอบหมาย
- ฟังเพลง A
- ฟังเพลง B
- ทีมเอ
- ทีมบี
อุปกรณ์ที่ใช้รหัสเกมอาจอยู่ในสถานะใดสถานะหนึ่งจากห้าสถานะนี้ แต่มีเพียงครั้งละหนึ่งเครื่องเท่านั้น และมีเพียงห้าสถานะนี้เท่านั้น
ฉันจะสมมติตลอดคู่มือว่าคุณกำลังใช้ตัวแก้ไข MakeCode ของ Microsoft ซึ่งสามารถดูได้ที่:
การใช้งานเต็มรูปแบบของเกมสามารถพบได้ที่นี่:
makecode.microbit.org/_CvRMtheLbRR3 ("microbit-demo-user" เป็นชื่อโครงการ)
และการใช้งานตัวควบคุมเครือข่ายหลัก ("root") สามารถพบได้ที่นี่:
makecode.microbit.org/_1kKE6TRc9TgE ("microbit-demo-root" เป็นชื่อโครงการ)
ฉันจะอ้างอิงถึงตัวอย่างเหล่านี้ตลอดการกวดวิชาของฉัน
ขั้นตอนที่ 1: ข้อควรพิจารณาในการออกแบบรูปภาพขนาดใหญ่
ก่อนที่เราจะเขียนโค้ดใดๆ เราต้องคิดก่อนว่าเราต้องการให้ end product ของเราเป็นอย่างไร กล่าวอีกนัยหนึ่งข้อกำหนดของแอปพลิเคชันคืออะไร? รหัสของเราควรบอกให้อุปกรณ์ทำอะไรเมื่อเสร็จแล้ว ฉันได้แบ่งฟังก์ชันการทำงานของแอปพลิเคชันหลักออกเป็น 6 หมวดหมู่ ซึ่งแต่ละประเภทสามารถพิจารณาได้จากมุมมองการออกแบบที่แตกต่างกัน
- เราต้องการควบคุมการทำงานของอุปกรณ์ตามสถานะปัจจุบัน
- เราต้องการให้อุปกรณ์ตอบสนองต่อการป้อนข้อมูลของผู้ใช้
- เราอาจต้องการแสดงภาพเคลื่อนไหวและกราฟิกโดยใช้จอแสดงผล LED 5 x 5
- เราต้องการเริ่มต้นค่าข้อมูลในหน่วยความจำของอุปกรณ์เมื่ออุปกรณ์บูทขึ้น
- เราต้องการส่งข้อมูลแบบไร้สายโดยใช้วิทยุของอุปกรณ์
- เราต้องการฟังและรับข้อมูลผ่านวิทยุของอุปกรณ์และประมวลผลตามนั้น
ให้ฉันเข้าไปดูรายละเอียดเพิ่มเติมเล็กน้อยเกี่ยวกับแต่ละรายการ
1. เราต้องการควบคุมการทำงานของอุปกรณ์ตามสถานะปัจจุบัน
เช่นเดียวกับโปรแกรมอื่นๆ ส่วนใหญ่ การรันคำสั่งที่ระบุโดยโค้ดจะเกิดขึ้นทีละบรรทัด เราต้องการให้อุปกรณ์ของเราดำเนินการตามคำสั่งบางอย่างตามสถานะภายใน ดังที่แสดงไว้ในแผนภาพที่ด้านบนของบทช่วยสอนนี้ เราสามารถเขียนชุดเงื่อนไขหลังจากทุกบล็อกของโค้ดที่ตรวจสอบว่าอุปกรณ์ควรทำ แต่วิธีการนี้อาจยุ่งยากมากอย่างรวดเร็ว ดังนั้นเราจะใช้การวนซ้ำแบบไม่มีที่สิ้นสุดที่ตรวจสอบตัวแปรเพียงตัวเดียวและอิงตามตัวแปรนั้นแทน ดำเนินการชุดคำสั่งเฉพาะหรือไม่ทำอะไรเลย ตัวแปรนี้จะถูกระบุโดยคำต่อท้าย "_state" ทั้งในแอปพลิเคชันผู้ใช้และแอปพลิเคชันรากของเรา
2. เราต้องการให้อุปกรณ์ตอบสนองต่อการป้อนข้อมูลของผู้ใช้
แม้จะมีการดำเนินการตามปกติของโค้ดที่เกิดขึ้นตามลำดับ กล่าวคือ ทีละบรรทัด เราต้องการให้อุปกรณ์ของเราตอบสนองต่อการกดปุ่มในขณะที่ลูปสถานะหลักกำลังกำหนดว่าอุปกรณ์ควรทำอะไรในช่วงเวลาใดก็ตาม เพื่อจุดประสงค์นั้น อุปกรณ์มีความสามารถในการส่งสัญญาณไปยังซอฟต์แวร์ระดับล่างที่โต้ตอบกับฮาร์ดแวร์ เรียกสิ่งที่เรียกว่าเหตุการณ์ เราสามารถเขียนโค้ดที่บอกให้อุปกรณ์ทำบางสิ่งเมื่อตรวจพบเหตุการณ์บางประเภท
3. เราต้องการแสดงภาพเคลื่อนไหวและกราฟิกโดยใช้จอแสดงผล LED 5 x 5
กลไกในการทำเช่นนี้ดูเหมือนจะง่าย แต่บล็อกแสดงรูปภาพเพิ่มการหน่วงเวลาที่ซ่อนอยู่ 400 ms เนื่องจากเราต้องการให้อุปกรณ์ของเราดำเนินการวนรอบสถานะต่อไปโดยมีเวลาแฝงน้อยที่สุด เราจึงต้องแก้ไขโค้ดจาวาสคริปต์เพื่อลดความล่าช้า
4. เราต้องการเริ่มต้นค่าข้อมูลในหน่วยความจำของอุปกรณ์เมื่ออุปกรณ์บูทขึ้น
ก่อนที่อุปกรณ์ของเราจะทำอะไร แอปพลิเคชันจำเป็นต้องโหลดข้อมูลลงในหน่วยความจำ ซึ่งรวมถึงตัวแปรคงที่ที่ตั้งชื่อตามความสามารถในการอ่านโค้ด ตัวแปรที่มีรูปภาพซึ่งอาจเป็นส่วนหนึ่งของแอนิเมชัน และตัวแปรตัวนับที่ต้องเริ่มต้นที่ 0 เพื่อให้ทำงานได้อย่างถูกต้อง เราจะลงเอยด้วยรายการชื่อตัวแปรจำนวนมากและค่าที่ได้รับมอบหมายใหม่ ตามสไตล์ส่วนตัว ฉันจะระบุค่าคงที่ เช่น ค่าที่ฉันไม่จำเป็นต้องเปลี่ยน โดยใช้ ALL_CAPS ฉันจะนำหน้าตัวระบุตัวแปรหลักด้วยชื่อหมวดหมู่ที่อ้างอิงถึงประเภทของวัตถุหรือประเภทที่ตัวระบุอยู่ภายใต้ นี่คือความพยายามที่จะทำให้โค้ดง่ายต่อการติดตาม ฉันจะไม่ใช้ชื่อตัวแปรเช่น "item" หรือ "x" เนื่องจากความกำกวมที่เกิดขึ้นเมื่อพยายามถอดรหัสโค้ด
5. เราต้องการส่งข้อมูลแบบไร้สายโดยใช้วิทยุของอุปกรณ์
นี่เป็นงานที่ค่อนข้างง่ายจริง ๆ เมื่อใช้ภาษาบล็อก MakeCode เราเพียงแค่ตั้งค่าอุปกรณ์ทั้งหมดเป็นกลุ่มวิทยุเดียวกันในเวลาบูต จากนั้นเมื่อเราต้องการส่งสัญญาณ เราก็สามารถส่งหมายเลขเดียวไปยังบล็อก "หมายเลขส่งวิทยุ" ที่เราได้รับ สิ่งสำคัญคือผู้ส่งและผู้รับต้องทำงานบนวิทยุกลุ่มเดียวกัน เพราะหากไม่เป็นเช่นนั้น พวกเขาจะส่งหรือรับในความถี่ที่ต่างกัน และการสื่อสารจะไม่ประสบผลสำเร็จ
6. เราต้องการฟังและรับข้อมูลผ่านวิทยุของอุปกรณ์และประมวลผลตามนั้น
โดยคำนึงถึงการพิจารณาเช่นเดียวกับรายการก่อนหน้านี้ เราจะรับฟังการส่งสัญญาณขาเข้าในลักษณะเดียวกับที่เราจะรับฟังข้อมูลจากผู้ใช้: ด้วยตัวจัดการเหตุการณ์ เราจะเขียนบล็อกของรหัสที่จะตรวจสอบสัญญาณที่เข้ามาและตรวจสอบว่าจะต้องดำเนินการใด ๆ โดยไม่รบกวนลูปสถานะหลักหรือไม่
นอกจากนี้ เราควรพิจารณาสั้น ๆ เกี่ยวกับการออกแบบแอปพลิเคชันรูทที่ง่ายกว่ามาก ซึ่งเป็นโปรแกรมที่อนุญาตให้อุปกรณ์ควบคุมเครือข่ายทั้งหมด ฉันจะไม่ใช้เวลามากกับสิ่งนี้เพราะมันง่ายกว่าการออกแบบด้านบนมากและส่วนใหญ่เป็นการทำซ้ำ ฉันได้แบ่งการทำงานของ root deice ออกเป็นสามประเภท
- เราต้องการที่จะสามารถเลือกสัญญาณได้
- เราต้องการที่จะสามารถส่งสัญญาณได้
--
1. เราต้องการที่จะสามารถเลือกสัญญาณได้
ซึ่งสามารถทำได้โดยเพียงแค่มีปุ่มวนซ้ำผ่านสัญญาณที่เป็นไปได้ เนื่องจากมีเพียงสามวิธีนี้ก็เพียงพอแล้ว ในเวลาเดียวกัน เราสามารถมีลูปที่แสดงสัญญาณที่เลือกซ้ำอย่างต่อเนื่อง ทำให้ผู้ใช้สามารถกดปุ่มและเห็นสัญญาณที่เลือกปรากฏบนจอแสดงผล LED ที่มีความหน่วงน้อยมาก
2. เราต้องการที่จะสามารถส่งสัญญาณได้
เนื่องจากมีสองปุ่ม เราจึงสามารถกำหนดปุ่มหนึ่งสำหรับการเลือกและอีกปุ่มหนึ่งเพื่อยืนยัน เช่นเดียวกับแอปพลิเคชันของผู้ใช้ เราเพียงแค่ส่งสัญญาณผ่านเครือข่ายเป็นตัวเลข ไม่มีข้อมูลอื่นที่จำเป็น
ฉันจะพูดเพิ่มเติมเกี่ยวกับโปรโตคอลสัญญาณอย่างง่ายในหัวข้อถัดไป
ขั้นตอนที่ 2: โปรโตคอลสัญญาณ: ภาษาง่าย ๆ สำหรับการสื่อสารผ่านเครือข่าย
สัญญาณต่อไปนี้ถือเป็นชุดของคำที่เป็นไปได้ทั้งหมดที่อุปกรณ์สามารถใช้เพื่อพูดคุยกัน เนื่องจากเครือข่ายนั้นเรียบง่าย ไม่มีอะไรจะพูดมาก ดังนั้นเราจึงสามารถแสดงสัญญาณทั้งสามนี้ด้วยค่าจำนวนเต็มอย่างง่าย
0. รีเซ็ต
- ตัวระบุในรหัส: SIG-R
- ค่าจำนวนเต็ม: 0
- วัตถุประสงค์: บอกให้อุปกรณ์ทั้งหมดที่อยู่ในระยะทำการทิ้งสิ่งที่พวกเขากำลังทำอยู่และทำตัวราวกับว่าเพิ่งบูทเครื่อง หากสัญญาณนี้ส่งไปถึงทุกอุปกรณ์ในเครือข่าย เครือข่ายทั้งหมดจะถูกรีเซ็ตและผู้ใช้สามารถเริ่มเกมใหม่ได้ สัญญาณนี้สามารถออกอากาศโดยอุปกรณ์รูทเท่านั้น
1. การแปลง A
- ตัวระบุในรหัส: SIG-A
- ค่าจำนวนเต็ม: 1
- วัตถุประสงค์: บอกอุปกรณ์ใดๆ ที่อยู่ในสถานะ LISTEN_A เมื่อได้รับสัญญาณการแปลงแล้ว ให้เปลี่ยนเป็นสถานะ TEAM_A
2. การแปลง B
- ตัวระบุในรหัส: SIG-B
- ค่าจำนวนเต็ม: 2
- วัตถุประสงค์: บอกอุปกรณ์ใดๆ ที่อยู่ในสถานะ LISTEN_B เมื่อได้รับสัญญาณการแปลงแล้ว ให้เปลี่ยนเป็นสถานะ TEAM_B
ขั้นตอนที่ 3: เราต้องการควบคุมการทำงานของอุปกรณ์ตามสถานะปัจจุบัน
ในที่สุด เราก็เริ่มเขียนโค้ดได้เลย
ขั้นแรก เปิดโครงการใหม่ใน Make Code
- สร้างฟังก์ชันใหม่ ฉันเรียก mine loop เพราะนี่คือ core loop ของแอปพลิเคชัน
- เพิ่มบล็อกวนซ้ำที่จะทำซ้ำไปเรื่อย ๆ ฉันใช้ while(true) เพราะค่า true จะไม่เป็นเท็จ ดังนั้นการควบคุมโฟลว์ของแอปพลิเคชันจะไม่ออกจากลูป
- เพิ่มบล็อก if-else ให้เพียงพอเพื่อตรวจสอบว่าอุปกรณ์อยู่ในสถานะที่เป็นไปได้ห้าสถานะหรือไม่
- สร้างตัวแปรเพื่อเก็บสถานะอุปกรณ์ปัจจุบัน
-
สร้างตัวแปรเพื่อเป็นตัวแทนของสถานะที่เป็นไปได้ทั้ง 5 สถานะ
หมายเหตุ: ไม่เป็นไรที่ตัวแปรเหล่านี้ยังไม่มีค่าที่กำหนด เราจะไปที่นั้น ณ จุดนี้ สำคัญกว่าที่เราเขียนโค้ดที่สะอาด อ่านง่าย
- เปลี่ยนแต่ละเงื่อนไขในบล็อก if-else เพื่อเปรียบเทียบสถานะปัจจุบันกับสถานะที่เป็นไปได้อย่างใดอย่างหนึ่ง
- ที่ด้านล่างของบล็อก if-else ให้เพิ่มการหยุดชั่วคราวเป็นจำนวนมิลลิวินาที และสร้างตัวแปรเพื่อเก็บตัวเลขนั้นไว้ เราจะเริ่มต้นในภายหลัง ตรวจสอบให้แน่ใจว่าตัวแปรมีชื่อที่สื่อความหมาย เช่น ขีดหรือการเต้นของหัวใจ เนื่องจากนี่คือแกนหลักของอุปกรณ์ การหยุดชั่วคราวนี้จะกำหนดความเร็วที่อุปกรณ์เรียกใช้ลูปหลัก ดังนั้นจึงเป็นค่าที่สำคัญมากและมีความสำคัญเกินกว่าจะเป็นตัวเลขวิเศษที่ไม่มีชื่อ
หมายเหตุ: อย่ากังวลกับบล็อคสีเทาในภาพที่สาม ฉันจะไปหาพวกนั้นทีหลัง
ขั้นตอนที่ 4: เราต้องการตอบสนองต่อการป้อนข้อมูลของผู้ใช้
ตอนนี้ เราต้องการบอกอุปกรณ์ถึงวิธีจัดการกับการกดปุ่ม ความคิดแรกอาจเป็นแค่การใช้บล็อค "เมื่อกดปุ่ม" ในหมวดหมู่อินพุต แต่เราต้องการการควบคุมที่ละเอียดกว่านี้ เราจะใช้บล็อก "ในเหตุการณ์จาก (X) ที่มีค่า (Y)" จากหมวดการควบคุมภายใต้ส่วนขั้นสูง เนื่องจากเราเชี่ยวชาญในบทช่วยสอนนี้
-
สร้างบล็อก "ในเหตุการณ์จาก…" สี่บล็อก
- สองรายการควรตรวจสอบแหล่งที่มาของเหตุการณ์ "MICROBIT_ID_BUTTON_A"
- สองรายการควรตรวจสอบแหล่งที่มาของเหตุการณ์ "MICROBIT_ID_BUTTON_B"
-
จากสองเหตุการณ์ที่กำหนดเป้าหมายแต่ละปุ่ม:
- ควรตรวจสอบเหตุการณ์ประเภท "MICROBIT_BUTTON_EVT_UP"
- ควรตรวจสอบเหตุการณ์ประเภท "MICROBIT_BUTTON_EVT_DOWN"
- หมายเหตุ: ตัวเลือกเหล่านี้เป็นตัวพิมพ์ใหญ่ทั้งหมดเป็นป้ายกำกับที่ใช้ในโค้ด micro:bit ระดับล่าง พวกมันเป็นเพียงตัวยึดตำแหน่งซึ่งจะถูกแทนที่ด้วยจำนวนเต็มในภายหลังเมื่อคอมไพล์โค้ดเป็นไบนารีที่ปฏิบัติการได้ มนุษย์ใช้ป้ายกำกับเหล่านี้ได้ง่ายกว่าการค้นหาว่าต้องใส่จำนวนเต็มใด แม้ว่าทั้งสองจะทำงานในลักษณะเดียวกัน
-
ตามสไตล์ฉันเลือกให้แต่ละ "ในเหตุการณ์จาก…" บล็อกการเรียกใช้ฟังก์ชันที่อธิบายเหตุการณ์ที่ยกขึ้น แม้ว่าจะไม่จำเป็นอย่างยิ่ง แต่ในความคิดของฉันสิ่งนี้ช่วยให้อ่านง่ายขึ้น หากต้องการทำเช่นนั้น พวกเขาสามารถใส่รหัสการจัดการเหตุการณ์ภายในบล็อก "ในเหตุการณ์จาก…" ได้
หมายเหตุ: บล็อกของรหัสที่จัดการการตอบสนองของอุปกรณ์ต่อเหตุการณ์นั้นเรียกว่า "ตัวจัดการเหตุการณ์" อย่างสังหรณ์ใจ
- เพิ่ม ในตัวจัดการเหตุการณ์แต่ละตัว โครงสร้าง if-else เดียวกันที่ใช้ในการแยกโฟลว์การควบคุมตามสถานะของอุปกรณ์เป็นโครงสร้างในลูปสถานะหลัก
-
เพิ่มบล็อคการกำหนดที่ปรับเปลี่ยนสถานะของอุปกรณ์ตามที่ระบุโดยไดอะแกรมสถานะของเรา
- เรารู้ว่าเมื่ออุปกรณ์อยู่ในสถานะ UNASSIGNED อุปกรณ์ควรตอบสนองต่อปุ่ม A ที่กดโดยการเปลี่ยนสถานะเป็น LISTEN_A และปุ่ม B ที่กดโดยการเปลี่ยนสถานะเป็น LISTEN_B
- เรายังทราบด้วยว่าเมื่ออุปกรณ์อยู่ในสถานะ LISTEN_A หรือ LISTEN_B อุปกรณ์ควรตอบสนองต่อปุ่ม A ที่ปล่อยและปุ่ม B ที่ปล่อยตามลำดับ โดยเปลี่ยนกลับเป็นสถานะ UNASSIGNED
-
สุดท้ายนี้ เรารู้ว่าเมื่ออุปกรณ์อยู่ในสถานะ TEAM_A หรือ TEAM_B อุปกรณ์ควรตอบสนองต่อปุ่ม A ที่กด และปุ่ม B ที่กดโดยการแพร่ภาพ SIG_A และโดยการแพร่ภาพ SIG_B ตามลำดับ
ไม่จำเป็นต้องกรอกรายละเอียดของสัญญาณกระจายเสียง ณ จุดนี้ เราจะไปที่นั่นในภายหลัง สิ่งสำคัญคือเราสั่งให้ฟังก์ชันเหล่านี้ใช้โค้ดที่เราจะเขียนโดยตั้งชื่อบล็อกของการกระทำนั้น เช่น broadcastSignalSIG_A ซึ่งอธิบายสิ่งที่ควรทำ ณ จุดนั้น
ขั้นตอนที่ 5: เราต้องการเริ่มต้นค่าข้อมูลในหน่วยความจำของอุปกรณ์เมื่ออุปกรณ์บูทขึ้น
ณ จุดนี้ เราใช้ตัวแปรจำนวนมาก (ชื่อสำหรับข้อมูล) แต่เราไม่ได้กำหนดค่าให้กับชื่อเหล่านั้นจริงๆ เราต้องการให้อุปกรณ์โหลดค่าของตัวแปรเหล่านี้ทั้งหมดลงในหน่วยความจำเมื่อบู๊ต ดังนั้นเราจึงวางการกำหนดค่าเริ่มต้นสำหรับตัวแปรเหล่านี้ในบล็อก "เมื่อเริ่มต้น"
นี่คือค่าที่เราต้องเริ่มต้น:
-
ค่าคงที่ของสัญญาณ ตามโปรโตคอลสัญญาณ ค่าจะต้องเป็น:
- SIG_R = 0
- SIG_A = 1
- SIG_B = 2
- หมายเหตุ: ฉันนำหน้าค่าคงที่เหล่านี้ด้วย "EnumSignals" เพื่อแสดงว่าตัวแปรเหล่านี้มีพฤติกรรมราวกับว่าเป็นส่วนหนึ่งของประเภทที่แจกแจงเรียกว่า Signals นี่คือวิธีที่ตัวแปรเหล่านี้สามารถนำไปใช้ในภาษาโปรแกรมอื่นๆ คำจำกัดความและคำอธิบายของประเภทที่แจกแจงอยู่นอกเหนือขอบเขตของบทช่วยสอนของฉัน หนึ่งอาจ Google ได้หากต้องการ คำนำหน้าเหล่านี้เป็นเพียงตัวเลือกโวหารและไม่จำเป็นสำหรับการทำงานที่เหมาะสมของโปรแกรม
-
ค่าคงที่ของรัฐ ซึ่งสามารถกำหนดได้เองตามอำเภอใจตราบเท่าที่มีค่า ฉันเลือกรูปแบบเพื่อใช้จำนวนเต็มที่ขึ้นจาก 0 ดังนี้:
- ไม่ได้มอบหมาย = 0
- LISTEN_A = 1
- LISTEN_B = 2
- TEAM_A = 3
- TEAM_B = 4
- หมายเหตุ: ฉันตัดสินใจเกี่ยวกับรูปแบบเดียวกันเกี่ยวกับคำนำหน้าสำหรับตัวแปรเหล่านี้เช่นกัน นอกจากนี้ ฉันจะพูดถึงว่าทุกอย่างเกี่ยวกับการมอบหมายเหล่านี้ ค่านิยม และลำดับ เป็นไปตามอำเภอใจโดยสมบูรณ์ ไม่สำคัญว่าค่าเหล่านี้จะสอดคล้องกันจากอุปกรณ์หนึ่งไปอีกอุปกรณ์หนึ่ง เนื่องจากค่าเหล่านี้ใช้ภายในเท่านั้นและไม่ใช่สำหรับการสื่อสารผ่านเครือข่าย สิ่งสำคัญคือตัวแปรมีค่าและสามารถเปรียบเทียบกันได้เพื่อดูว่ามีค่าเท่ากันหรือไม่
- เพื่อให้อ่านง่าย ให้ใช้ค่าคงที่ BOOT_STATE และตั้งค่าเป็น UNASSIGNED สิ่งนี้ทำให้ความจริงที่ว่าเรารีเซ็ตเป็นสถานะบูต แทนที่จะเป็นสถานะกำหนดเอง ชัดเจนยิ่งขึ้นเมื่ออุปกรณ์ได้รับสัญญาณรีเซ็ต ซึ่งเราจะดำเนินการในภายหลัง
-
ค่าคงที่ของแอนิเมชัน ใช้ในขั้นตอนต่อไปนี้เพื่อสร้างแอนิเมชันที่อนุญาตให้มีการขัดจังหวะเวลาแฝงที่ต่ำมากผ่านการป้อนข้อมูลของผู้ใช้ เรายังไม่เคยใช้สิ่งเหล่านี้มาก่อน แต่จะอธิบายและใช้อย่างแน่นอนในหัวข้อต่อไปนี้ ความหมายของสิ่งเหล่านี้ควรเข้าใจได้ง่ายเนื่องจากชื่อของพวกเขา
- TICKS_PER_FRAME_LOADING_ANIMATION = 50
- MS_PER_DEVICE_TICK = 10
- MS_PER_FRAME_BROADCAST_ANIMATION = 500
- MICROSECONDS_PER_MILLISECOND = 1,000
- NUMBER_OF_FRAMES_IN_LOADING_ANIMATION = 4
-
ตัวแปรอื่นสำหรับแอนิเมชั่น คราวนี้เป็นตัวนับที่ไม่คงที่แน่นอน เช่นเดียวกับตัวนับส่วนใหญ่ เราเริ่มต้นเป็น 0
iTickLoadingAnimation = 0
-
สร้างตัวแปรสองชุดเพื่อเก็บเฟรมของภาพเคลื่อนไหว ภาพแรกซึ่งผมเรียกว่า "การโหลดภาพเคลื่อนไหว" ควรมีสี่ภาพ (ซึ่งคุณอาจเดาได้จากการกำหนดค่าเริ่มต้นคงที่ครั้งล่าสุด) และภาพที่สองซึ่งผมเรียกว่า "ภาพเคลื่อนไหวออกอากาศ" ซึ่งควรมีสามภาพ ฉันแนะนำให้ตั้งชื่อตัวแปรให้สอดคล้องกับเฟรมของแอนิเมชั่น เช่น ringAnimation0, ringAnimation1…
สร้างค่ารูปภาพเดียวกันกับที่ฉันทำหรือสร้างรูปภาพที่เป็นต้นฉบับและเจ๋งกว่า
- สุดท้ายเราต้องตั้งค่ากลุ่มวิทยุของอุปกรณ์เป็น 0 โดยใช้บล็อก "ชุดวิทยุ (X)"
- หรือเขียนข้อความ "การเริ่มต้นเสร็จสมบูรณ์" ไปยังเอาต์พุตแบบอนุกรมเพื่อบอกผู้ใช้ว่าทุกอย่างดำเนินไปอย่างราบรื่น
- เมื่อตั้งค่าอุปกรณ์เสร็จแล้ว เราสามารถเรียกใช้ฟังก์ชัน state loop ได้
ขั้นตอนที่ 6: เราต้องการแสดงภาพเคลื่อนไหวและกราฟิกโดยใช้จอแสดงผล LED 5 X 5
และตอนนี้สำหรับบางสิ่งที่แตกต่างไปจากเดิมอย่างสิ้นเชิง
เราต้องการแสดงแอนิเมชั่นสองสามตัวและอักขระสองสามตัว แต่เราไม่ต้องการขัดจังหวะการวนซ้ำของสถานะหลัก ขออภัย บล็อกที่แสดงรูปภาพและสตริงข้อความมีความล่าช้า 400 ms โดยค่าเริ่มต้น ไม่มีทางที่จะเปลี่ยนแปลงสิ่งนี้ได้หากไม่แก้ไขการแสดงโค้ดจาวาสคริปต์ ดังนั้นนี่คือสิ่งที่เราจะทำ
- สร้างฟังก์ชันสำหรับแต่ละภาพ ซึ่งจะทำให้สามารถใช้บล็อกเดียวเพื่อแสดงภาพแทนการแก้ไขจาวาสคริปต์ทุกครั้ง ในโปรแกรมเฉพาะนี้ ไม่มีการใช้รูปภาพมากกว่าหนึ่งครั้ง แต่ฉันยังคงคิดว่าสไตล์นี้ทำให้โค้ดอ่านง่ายขึ้น
- เพิ่มในแต่ละฟังก์ชันใหม่ บล็อก "แสดงรูปภาพ (X) ที่ออฟเซ็ต 0" พร้อมชื่อตัวแปรรูปภาพที่เกี่ยวข้องแทนที่ (X)
-
เพิ่มในลูปสถานะหลัก "แสดงสตริง (X)" บล็อกแต่ละบล็อกนอกเหนือจากที่จัดการสถานะ UNASSIGNED เพิ่มอักขระให้อุปกรณ์แสดงเพื่อระบุสถานะต่างๆ นี่คือสิ่งที่ฉันทำ:
- LISTEN_A: 'ก'
- LISTEN_B: 'ข'
- TEAM_A: 'เอ'
-
TEAM_B: 'บี'
สำหรับสถานะ UNASSIGNED ให้เรียกใช้ฟังก์ชันที่จะอัปเดตภาพเคลื่อนไหวการโหลด เราจะกรอกรายละเอียดของฟังก์ชันด้านล่างนี้
- เปลี่ยนเป็นโหมดจาวาสคริปต์
- ค้นหาทุกการโทรไปยัง X.showImage(0) และ basic.showString(X)
-
เปลี่ยนทุกอันเป็น X.showImage(0, 0) หรือ basic.showString(X, 0)
- การเพิ่มอาร์กิวเมนต์พิเศษนี้จะตั้งค่าการหน่วงเวลาหลังจากการดำเนินการเป็น 0 โดยค่าเริ่มต้น ค่านี้จะถูกละไว้ และอุปกรณ์จะหยุดชั่วคราวเป็นเวลา 400 มิลลิวินาทีหลังจากการดำเนินการของแต่ละบล็อกเหล่านี้
- ตอนนี้ เรามีกลไกที่แทบไม่มีความหน่วงแฝงในการแสดงรูปภาพของเราในบล็อกแอนิเมชั่น ซึ่งตอนนี้เราสามารถสร้างได้
ขั้นแรก เราจะสร้างฟังก์ชันแอนิเมชั่นการออกอากาศที่ค่อนข้างง่าย มันง่ายกว่าเพราะเราไม่ต้องการให้ผู้ใช้ทำอะไรจนกว่าฟังก์ชันจะเสร็จสมบูรณ์ เพื่อหยุดพวกเขาจากการสแปมฟังก์ชันออกอากาศ เพื่อให้บรรลุสิ่งนี้ เราสามารถจำกัดโฟลว์การควบคุมไว้ที่บล็อกจนกว่าฟังก์ชันจะเสร็จสมบูรณ์ ซึ่งเป็นพฤติกรรมมาตรฐาน
- สร้างฟังก์ชันที่จะแสดงภาพเคลื่อนไหวการออกอากาศ
- ภายในบล็อกนั้น ให้เพิ่มการเรียกใช้ฟังก์ชันสามรายการ หนึ่งรายการต่อเฟรมของแอนิเมชันแต่ละเฟรม ตามลำดับที่ควรจะแสดง
-
เพิ่มบล็อก "รอ (เรา) (X)" หลังจากการเรียกใช้ฟังก์ชันการแสดงภาพแต่ละครั้ง
หมายเหตุ: บล็อกนี้จากส่วนการควบคุมขั้นสูงจะไปไกลกว่า "หยุดชั่วคราว (ms) " ซึ่งจะทำให้ตัวประมวลผลหยุดทำงานจนหมดเวลาที่กำหนด เมื่อใช้บล็อกหยุดชั่วคราว อุปกรณ์อาจทำงานอื่นเบื้องหลังได้ สิ่งนี้เป็นไปไม่ได้ด้วยบล็อกการรอ
- แทนที่ (X) ด้วย (MS_PER_FRAME_BROADCAST_ANIMATION x MICROSECONDS_PER_MILLISECOND)
- แอนิเมชั่นควรทำงานอย่างถูกต้องแล้ว
ประการที่สอง เราจะสร้างกลไกสำหรับการแสดงภาพเคลื่อนไหวการโหลด แนวคิดเบื้องหลังนี้คือการอัปเดตจอแสดงผล LED ในช่วงเวลาที่กำหนด ซึ่งเรากำหนดไว้ในตัวแปร MS_PER_DEVICE_TICK ค่านี้ ความยาวของขีดอุปกรณ์ คือจำนวนมิลลิวินาทีที่อุปกรณ์หยุดชั่วคราวหลังจากเสร็จสิ้นการวนซ้ำของสถานะแต่ละครั้ง เนื่องจากค่านี้มีขนาดเล็กเพียงพอ เราสามารถอัปเดตการแสดงผลได้หนึ่งครั้งในระหว่างการวนซ้ำของการแสดงผลแต่ละครั้ง และจะปรากฏต่อผู้ใช้ว่าภาพเคลื่อนไหวดำเนินไปอย่างราบรื่น และเมื่อสถานะเปลี่ยน จะมีเวลาแฝงระหว่างอินพุตของผู้ใช้น้อยมาก กำลังปรับปรุงจอแสดงผล ด้วยการนับขีด ซึ่งเราทำกับตัวแปร iTickLoadingAnimation เราสามารถแสดงเฟรมที่เหมาะสมของแอนิเมชั่นได้
- สร้างฟังก์ชั่นที่จะอัปเดตแอนิเมชั่นการโหลด
-
เพิ่มเงื่อนไขเพื่อตรวจสอบว่าตัวนับขีดถึงค่าสูงสุดหรือไม่ เงื่อนไขนี้จะเป็นจริงหากค่าของตัวนับติ๊กมากกว่าจำนวนเฟรมในแอนิเมชั่นการโหลดคูณด้วยจำนวนขีดที่จะแสดงแต่ละเฟรม
หากเงื่อนไขเป็นจริง ให้รีเซ็ต iTickLoadingAnimation เป็น 0
-
เพิ่มบล็อกของเงื่อนไข if-else สิ่งเหล่านี้จะกำหนดเฟรมของแอนิเมชั่นที่จะแสดง
สำหรับแต่ละเฟรมของแอนิเมชั่น หากตัวนับติ๊กน้อยกว่าจำนวนติ๊กในแต่ละแอนิเมชั่นคูณด้วยหมายเลขเฟรมของแอนิเมชั่น (เริ่มต้นที่ 1) ให้แสดงเฟรมนั้น มิฉะนั้นให้ตรวจสอบว่าเฟรมถัดไปเป็นเฟรมเดียวหรือไม่ ถูกแสดง
- ที่ด้านล่างของบล็อก เพิ่ม iTickLoadingAnimation
- แอนิเมชั่นควรทำงานอย่างถูกต้องแล้ว
หมายเหตุ: บล็อคสีเทาทั้งหมดที่ปรากฏในตัวอย่างของฉันถูกสร้างขึ้นเมื่อมีการแก้ไขการแสดงจาวาสคริปต์ของบล็อก หมายความว่าบล็อกแสดงถึงโค้ดจาวาสคริปต์ที่ไม่สามารถแสดงโดยใช้ชุดบล็อกมาตรฐานและต้องแก้ไขในรูปแบบข้อความ
ขั้นตอนที่ 7: เราต้องการส่งข้อมูลแบบไร้สายโดยใช้วิทยุของอุปกรณ์
ขั้นตอนนี้สั้นกว่าครั้งก่อนมาก อันที่จริง อาจเป็นขั้นตอนที่สั้นที่สุดในบทช่วยสอนทั้งหมดนี้
จำได้ว่าเมื่อเราตั้งโปรแกรมการตอบสนองของอุปกรณ์ต่อการป้อนข้อมูลของผู้ใช้ ฉันมีสองช่วงตึกในภาพหน้าจอที่ไม่ได้อธิบายไว้ในส่วนนั้น สิ่งเหล่านี้เป็นการเรียกใช้ฟังก์ชันที่ส่งสัญญาณทางวิทยุ โดยเฉพาะอย่างยิ่ง:
-
บนปุ่ม A กด:
-
หากอุปกรณ์อยู่ในสถานะ TEAM_A:
สัญญาณออกอากาศ SIG_A
-
-
บนปุ่ม B กด:
-
หากอุปกรณ์อยู่ในสถานะ TEAM_B
สัญญาณออกอากาศ SIG_B
-
สร้างฟังก์ชันนี้หากยังไม่มี
ในแต่ละหน้าที่:
- เรียกฟังก์ชันภาพเคลื่อนไหวออกอากาศ การดำเนินการนี้จะบล็อกไม่ให้สิ่งอื่นเกิดขึ้นจนกว่าจะเสร็จสิ้น ซึ่งจะอยู่ใน MS_PER_FRAME_BROADCAST_ANIMATION * 3 = 1.5 วินาที ค่าคงที่คูณด้วยสามเนื่องจากมีสามเฟรมในแอนิเมชั่น นี่เป็นกฎเกณฑ์และสามารถเพิ่มได้อีกหากการอัพเกรดด้านสุนทรียศาสตร์นั้นยอดเยี่ยมเพียงพอ จุดประสงค์ที่สองของแอนิเมชั่นนี้คือเพื่อป้องกันไม่ให้ผู้ใช้สแปมฟังก์ชันออกอากาศ
- เพิ่มบล็อก "หมายเลขส่งวิทยุ (X)" โดยที่ค่าคงที่ของสัญญาณที่กล่าวถึงในชื่อฟังก์ชัน
นั่นคือทั้งหมดที่จำเป็นในการออกอากาศทางวิทยุ
ขั้นตอนที่ 8: เราต้องการฟังและรับข้อมูลผ่านวิทยุของอุปกรณ์และประมวลผลตามนั้น
นี่เป็นขั้นตอนสุดท้ายในการสร้างแอปพลิเคชันหลัก
เราจะบอกอุปกรณ์ถึงวิธีประมวลผลสัญญาณวิทยุที่เข้ามา อันดับแรก อุปกรณ์ของเราจะตั้งชื่อสัญญาณที่ได้รับ จากนั้น ตามค่าของสัญญาณนั้น มันจะตัดสินใจว่าจะต้องดำเนินการใด หากมี
อันดับแรก:
- สร้างบล็อกของรหัสที่ขึ้นต้นด้วยบล็อก "รับวิทยุ (X)"
- หรือกำหนดค่าที่ได้รับนั้นให้กับตัวแปรอื่นด้วยชื่อที่สื่อความหมายมากกว่า
- เรียกใช้ฟังก์ชันที่จะประมวลผลสัญญาณ
ประการที่สอง ในฟังก์ชันการประมวลผลสัญญาณ:
- สร้างบล็อกของคำสั่ง if-else ที่สาขาควบคุมโฟลว์ตามค่าของสัญญาณ
-
ถ้าสัญญาณเป็น SIG_R
ตั้งค่าสถานะของอุปกรณ์เป็น BOOT_STATE (นี่คือเหตุผลที่เราสร้างค่าคงที่ก่อนหน้านี้)
- หากสัญญาณเป็น SIG_A และหากสถานะปัจจุบันคือ LISTEN_A
ตั้งค่าสถานะของอุปกรณ์เป็น TEAM_A
-
หากสัญญาณเป็น SIG_B และหากสถานะปัจจุบันคือ LISTEN_B
ตั้งค่าสถานะของอุปกรณ์เป็น TEAM_B
แค่นั้นแหละ. การสมัครเสร็จสิ้น
ขั้นตอนที่ 9: อุปกรณ์รูท: เราต้องการให้เลือกสัญญาณ
ตอนนี้ เราจะเขียนแอปพลิเคชันอย่างง่ายสำหรับอุปกรณ์ "รูท" กล่าวคือ อุปกรณ์ที่จะควบคุมเครือข่าย
อุปกรณ์นี้จะต้องทำหน้าที่สองอย่าง:
- เราต้องการให้ผู้ใช้เลือกหนึ่งในสัญญาณของเรา
- เราต้องการให้ผู้ใช้กระจายสัญญาณ
เนื่องจากข้อกำหนดของแอปพลิเคชันนี้เป็นชุดย่อยของก่อนหน้านี้ ฉันจะให้ภาพรวม แต่ฉันจะไม่ลงรายละเอียดมากเท่าที่ฉันเคยมีมาก่อน ภาพด้านบนมีรหัสที่สมบูรณ์สำหรับแอปพลิเคชันนี้
เพื่อให้ผู้ใช้เลือกสัญญาณได้:
-
เริ่มต้น 5 ตัวแปรในบล็อก "เมื่อเริ่มต้น":
- สามสัญญาณ (0, 1, 2)
- จำนวนสัญญาณ (3)
- ตัวแปรเพื่อเก็บสัญญาณที่เลือกไว้ในปัจจุบัน (ตั้งค่าเริ่มต้นเป็นสัญญาณแรก 0)
-
กดปุ่ม A:
- เพิ่มสัญญาณที่เลือก
-
ตรวจสอบว่าสัญญาณที่เลือกมากกว่าหรือเท่ากับจำนวนสัญญาณ
ถ้าใช่ ให้ตั้งค่าสัญญาณที่เลือกเป็น 0
- หลังจากบล็อกการเริ่มต้น ให้เรียกใช้ลูป "ตลอดไป" ที่แสดงค่าสัญญาณที่เลือกในปัจจุบันโดยไม่มีการหน่วงเวลา
เพื่อให้ผู้ใช้งานสามารถถ่ายทอดสัญญาณได้
- ตั้งค่ากลุ่มวิทยุเป็น 0 ในบล็อก "เมื่อเริ่มต้น"
-
กดปุ่ม B:
ออกอากาศสัญญาณที่เลือกโดยใช้บล็อก "หมายเลขส่งวิทยุ (X)"
แค่นั้นแหละ. แอปพลิเคชันรูทโหนดนั้นง่ายมาก
ขั้นตอนที่ 10: เราเสร็จแล้ว
ด้านบนเป็นรูปภาพของอุปกรณ์ที่เรียกใช้แอปพลิเคชัน ทั้งสองทางด้านขวากำลังเรียกใช้แอปพลิเคชัน "ผู้ใช้" หลัก และอีกตัวหนึ่งทางด้านซ้ายกำลังเรียกใช้แอปพลิเคชัน "รูท"
ฉันสาธิตเกมนี้ที่ CS Connections 2018 ซึ่งเป็นการประชุมภาคฤดูร้อนเป็นเวลา 1 สัปดาห์สำหรับครูระดับมัธยมศึกษาตอนต้นและระดับมัธยมศึกษาเกี่ยวกับการศึกษาด้านวิทยาการคอมพิวเตอร์ ฉันแจกอุปกรณ์ให้ครูประมาณ 40 เครื่องและอธิบายกฎ ส่วนใหญ่พบว่าเกมมีความบันเทิง และหลายคนพบว่ามันสับสนจนคิดไม่ออกว่าจะเล่นอย่างไร การสาธิตนั้นสั้น แต่เราพบว่าเกมนี้สนุกท่ามกลางฝูงชนที่หลากหลาย
ดูข้อมูลเพิ่มเติมเกี่ยวกับ CS Connections 2018 ได้ที่นี่
แนะนำ:
BBC Micro:bit and Scratch - เกมบังคับพวงมาลัยและการขับขี่แบบโต้ตอบ: 5 ขั้นตอน (พร้อมรูปภาพ)
BBC Micro:bit and Scratch - Interactive Steering Wheel & Driving Game: หนึ่งในงานที่ได้รับมอบหมายในชั้นเรียนของฉันในสัปดาห์นี้คือการใช้ BBC Micro:bit เพื่อเชื่อมต่อกับโปรแกรม Scratch ที่เราได้เขียนไว้ ฉันคิดว่านี่เป็นโอกาสที่ดีที่จะใช้ ThreadBoard ของฉันเพื่อสร้างระบบฝังตัว! แรงบันดาลใจของฉันสำหรับรอยขีดข่วน p
วิธีเรียกใช้เซอร์โวมอเตอร์โดยใช้ Moto:bit ด้วย Micro:bit: 7 ขั้นตอน (พร้อมรูปภาพ)
วิธีเรียกใช้เซอร์โวมอเตอร์โดยใช้ Moto:bit ด้วย Micro:bit: วิธีหนึ่งในการขยายฟังก์ชันการทำงานของ micro:bit คือการใช้บอร์ดชื่อ moto:bit โดย SparkFun Electronics (ประมาณ 15-20 เหรียญสหรัฐ) มันดูซับซ้อนและมีคุณสมบัติมากมาย แต่ก็ไม่ยากที่จะเรียกใช้เซอร์โวมอเตอร์จากมัน Moto:bit ช่วยให้คุณ
Plug & Play Tiny Raspberry Pi Network Server: 6 ขั้นตอน (พร้อมรูปภาพ)
Plug & Play Tiny Raspberry Pi Network Server: เมื่อเร็ว ๆ นี้ฉันได้ Raspberry Pi 1 รุ่น A+ สองตัวในราคาถูก หากคุณไม่เคยได้ยินชื่อ Pi Model A มาก่อน แสดงว่า Raspberry Pi เป็นฟอร์มแฟคเตอร์แรกสุดของ Raspberry Pi ที่ใหญ่กว่า Pi Zero และเล็กกว่า Raspberry Pi มาตรฐาน ฉันอยากจะ
การเขียนโปรแกรม Micro:Bit Robot & Joystick:Bit Controller ด้วย MicroPython: 11 ขั้นตอน
การเขียนโปรแกรม Micro:Bit Robot & Joystick:Bit Controller ด้วย MicroPython: สำหรับ Robocamp 2019 ค่ายหุ่นยนต์ภาคฤดูร้อนของเรา คนหนุ่มสาวอายุ 10-13 ปีกำลังบัดกรี ตั้งโปรแกรม และสร้าง 'หุ่นยนต์น้ำหนักเกิน' ของ BBC micro:bit ตลอดจนการเขียนโปรแกรม micro:bit เพื่อใช้เป็นรีโมตคอนโทรล หากคุณอยู่ที่ Robocamp ให้เล่นสกี
การวัดแสงและสีด้วย Pimoroni Enviro:bit สำหรับ Micro:bit: 5 ขั้นตอน
การวัดแสงและสีด้วย Pimoroni Enviro:bit สำหรับ Micro:bit: ฉันเคยทำงานกับอุปกรณ์บางตัวที่อนุญาตให้วัดแสงและสีได้ก่อนหน้านี้ และคุณอาจพบมากเกี่ยวกับทฤษฎีที่อยู่เบื้องหลังการวัดดังกล่าวในคำแนะนำต่างๆ ที่นี่และที่นี่ Pimoroni มี เพิ่งเปิดตัว enviro:bit ซึ่งเป็นส่วนเสริมสำหรับ m