Micro:bit Code Examples
ตัวอย่างโค้ดไมโครไพธอนสำหรับบอร์ดไมโครบิต
การเรียนรู้จากตัวอย่างโค้ด ก็เป็นวิธีหนึ่งที่ช่วยทำให้รู้จักคำสั่งต่าง ๆ ของไมโครไพธอนสำหรับไมโครบิตได้ง่ายขึ้น ลองมาดูตัวอย่างโค้ดที่สามารถนำไปทดลองกับบอร์ดไมโครบิตได้
ตัวอย่างโค้ดไมโครไพธอนสำหรับไมโครบิตในเอกสารนี้ สามารถนำไปใช้ได้กับ MicroPython Online Editor แต่ในบางกรณีแนะนำให้ลองใช้ซอฟต์แวร์ที่เป็น Offline Editor เช่น Mu Editor หรือ Thonny IDE เป็นต้น
โค้ดตัวอย่างที่ 1: การแสดงข้อความและสัญลักษณ์บน 5x5 LED Display
การทำงานของโค้ดตัวอย่างนี้ เริ่มต้นด้วยการแสดงข้อความเป็นภาษาอังกฤษ "Hello, World!"
ด้วยคำสั่ง display.scroll()
(ทำเพียงครั้งเดียว) เนื่องจากมีหลายตัวอักษร จึงใช้วิธีแสดงทีละตัว แล้วเลื่อนจากขวาไปซ้าย จนครบตัวอักษรสุดท้ายของข้อความ
ในการแสดงข้อความแบบเลื่อนไป โดยใช้คำสั่ง display.scroll()
เราสามารถกำหนดช่วงเวลาในการอัปเดตสกรีน 5x5 LED Display ได้ด้วย เช่น 100 (หน่วยเป็นมิลลิวินาที) ถ้าต้องการให้เกิดการเปลี่ยนแปลงช้าลง ก็ให้เพิ่มค่าตัวเลข
ถัดไปมีประโยคคำสั่ง while เพื่อทำขั้นตอนซ้ำ ได้แก่ การแสดงรูปสัญลักษณ์ 'หัวใจ' หรือImage.HEART
โดยใช้คำสั่ง display.show()
และให้เว้นช่วงเวลาประมาณ 1000 มิลลิวินาที โดยใช้คำสั่ง sleep()
ตามด้วยคำสั่ง display.clear()
เพื่อเคลียร์การแสดงผล
ข้อสังเกต: คำสั่งต่าง ๆ ที่เกี่ยวข้องกับไมโครไพธอนสำหรับไมโครบิต จะอยู่ภายใต้ชื่อของแพคเกจหรือโมดูลชื่อ microbit
ดังนั้นในบรรทัดแรกของโค้ด จึงมีคำสั่ง from microbit import *
ถ้าต้องการลองใช้รูปไอคอนของไมโครไพธอนที่ได้มีการกำหนดไว้แล้ว (Built-in Images) ก็สามารถดูได้จากเอกสารในหัวข้อ Images ตัวอย่างเช่น รูปกราฟิกแสดงอารมณ์ความรู้สึก
Image.HAPPY
(รู้สึกมีความสุข)Image.SMILE
(รูปหน้ายิ้ม)Image.SAD
(รู้สึกเศร้า)Image.CONFUSED
(รู้สึกสับสน)Image.ANGRY
(รู้สึกโกรธ)Image.ASLEEP
(รู้สึกง่วงนอน)Image.SURPRISED
(รู้สึกประหลาดใจ)
โค้ดต่อไปนี้ สาธิตการแสดงรูปสัญลักษณ์ โดยระบุไว้ในอาร์เรย์ (Array) หรือ List ในภาษาไพธอน และจะเลือกมาแสดงผลทีละรูปตามลำดับ แล้ววนซ้ำไปเรื่อย ๆ
เราสามารถกำหนดรูปกราฟิกขนาด 5x5 พิกเซลได้เอง (User-defined Images) สำหรับนำไปแสดงผลบน LED Display โดยใช้คำสั่ง Image()
และ display.show()
การใช้คำสั่ง Image()
เป็นการกำหนดค่าพิกเซลขนาด 5x5 (หนึ่งพิกเซลสำหรับ LED หนึ่งดวง) มีค่าความสว่างได้ 0..9 (0=LED OFF และ 9=สว่างมากที่สุด) ในแต่ละแถว เรียงจากซ้ายไปขวา และเรียงจากแถวบนลงล่าง
ยกตัวอย่าง เช่น ถ้าต้องการสร้างรูปกากบาท (Cross Mark) เราก็กำหนดรูปกราฟิกดังนี้
โค้ดตัวอย่างที่ 2: การสุ่มเลข 1-6 เมื่อกดปุ่มหรือเขย่าบอร์ด
ถ้าต้องการทำให้บอร์ดไมโครบิต มีพฤติกรรมการทำงานเหมือน (Electronic Dice) เช่น เมื่อกดปุ่ม A หรือเขย่าบอร์ด (Shaking) จะทำให้เกิดการสุ่มเลข เหมือนการทอยลูกเต๋า จะเขียนโค้ดอย่างไร ?
โค้ดตัวอย่างนี้ เมื่อมีการกดปุ่ม A ในแต่ละครั้ง จะมีการสุ่มเลขที่เป็นจำนวนเต็ม (Integer) ที่จะได้ค่าอยู่ระหว่าง 1 ถึง 6 โดยใช้คำสั่ง random.randint()
เก็บไว้ในตัวแปรชื่อ number
แล้วจึงนำค่านี้ไปแสดงผล โดยเรียกใช้ฟังก์ชัน showRandomNumber()
ที่ได้สร้างขึ้นเอง แต่ถ้ามีการกดปุ่ม B ก็จะเป็นการเคลียร์การแสดงผลบน LED Display ด้วยคำสั่ง display.clear()
ข้อสังเกต: การใช้คำสั่งของ random
เพื่อสุ่มเลขนั้น ไม่ใช่การสุ่มเลขที่แท้จริง (True Random Number Generation) แต่ใช้อัลกอริทึมทางคณิตศาสตร์ในการกำหนดตัวเลขในลำดับถัดไป (จึงเป็นแบบ Pseudo-random Number Generation)
เมื่อโปรแกรมเริ่มทำงานในแต่ละครั้ง เราสามารถกำหนดค่าเริ่มต้น (หรือ Seed Value) โดยใช้คำสั่ง random.seed()
ก่อนเริ่มใช้คำสั่งของ random
สำหรับการสุ่มตัวเลข ในตัวอย่างนี้ ได้ใช้ค่าเลขจำนวนเต็มที่อ่านได้จากขา P0 แบบแอนะล็อกของบอร์ดไมโครบิต (แต่ที่ขา P0 ไม่ได้ต่อใช้งาน) มาใช้เป็นค่าเริ่มต้น
การตรวจสอบเงื่อนไขไปตามลำดับนั้น เราได้ใช้ประโยคคำสั่งแบบ if-elif โดยมีเงื่อนไขในการตรวจสอบ
ดูว่า มีการกดปุ่ม A หรือไม่ ซึ่งเราจะใช้คำสั่ง
button_a.was_pressed()
ถัดไปดูว่า มีการกดปุ่ม B หรือไม่ โดยใช้คำสั่ง
button_b.was_pressed()
คำถามสำหรับการทดลองโดยใช้ฮาร์ดแวร์:
ถ้าไม่ได้ต่อขา P0 กับวงจรใด ๆ (ไม่มีการใช้งานกับวงจรภายนอก) และอ่านอินพุตแบบแอนะล็อกจากขา P0 ของบอร์ดไมโครบิต จะได้ค่าที่แตกต่างกันไปหรือไม่ ? ลองมาดูโค้ดตัวอย่าง เมื่อกดปุ่ม A แต่ละครั้ง จะอ่านค่าจากอินพุต P0 เช่น ทั้งหมด 10 ครั้ง
เมื่ออัปโหลดโค้ดไปยังบอร์ด ให้กดปุ่ม Open Serial เพื่อรับค่าจากบอร์ด ซึ่งจะเป็นข้อความที่ถูกส่งกลับมายังคอมพิวเตอร์ โดยใช้คำสั่ง print()
แต่ถ้าต้องการปิดการรับข้อมูลจาก Serial ให้กดปุ่ม Close Serial
ลองกดปุ่ม A หลายครั้ง โดยไม่ใช้นิ้วสัมผัสที่ขา P0 ที่บริเวณ Edge Connector และอยู่ใกล้ปุ่ม A) และเปรียบเทียบกับการใช้นิ้วสัมผัส
โค้ดตัวอย่างถัดไป ได้เปลี่ยนจากการแสดงตัวเลข ให้เป็นการแสดงรูปกราฟิกแทน (ใช้จำนวนจุด หรือ Dots ที่มีจำนวนตามตัวเลขที่สุ่มได้) ในตัวอย่างนี้ เราสุ่มเลขที่มีค่าระหว่าง 1 ถึง 6 ไว้ในตัวแปร number
แล้วนำค่าที่ได้นี้ (ลบออก 1) ไปใช้อ้างอิง Image
จากตัวแปรแบบอาร์เรย์ image_list
ซึ่งเริ่มต้นนับที่ index
เท่ากับ 0
ในการตรวจสอบเหตุการณ์หรือเงื่อนไข เพื่อดูว่า มีการเขย่าบอร์ดเกิดขึ้นหรือไม่ เราจะใช้คำสั่ง accelerometer.is_gesture()
ที่ระบุว่าเป็น "shake" ถ้ามีการเขย่าบอร์ด ให้ตรวจสอบดูเงื่อนไขถัดไปในการอัปเดตค่าสุ่มตัวเลขถัดไปคือ จะต้องเกิดขึ้นหลังจากครั้งที่แล้วอย่างน้อย 1000 มิลลิวินาที (msec)
โค้ดตัวอย่างมีการใช้คำสั่ง time.ticks_ms()
เพื่ออ่านค่าเวลาของระบบ (หน่วยเป็น msec) และใช้คำสั่ง time.ticks_diff()
เพื่อหาผลต่างระหว่างช่วงเวลา (Time Difference) ผลต่างของค่าตัวเลขเวลาในปัจจุบันกับค่าตัวเวลาในอดีตที่บันทึกเก็บไว้ (ผลต่างระหว่าง now_shake
กับ last_shake
) จะต้องมีค่ามากกว่า 1000 มิลลิวินาที
โค้ดตัวอย่างที่ 3: สุ่มตำแหน่งเพื่อทำให้ LED สว่าง 5 จุด
ตัวอย่างถัดไปสาธิตการสุ่มหาตำแหน่ง (x,y) บน LED Matrix Display ซึ่งจะมีทั้งหมด 5 ตำแหน่งที่ทำให้ LED สว่าง (ON) โดยมีเงื่อนไขว่า ในแต่ละแถวแนวนอนหรือแนวตั้ง จะต้องไม่ซ้ำกัน
ในการกำหนดสถานะ ON/OFF หรือกำหนดค่าความสว่าง (0..9) ให้ LED ในตำแหน่งหรือพิกัดที่ต้องการ เราจะใช้คำสั่ง display.set_pixel()
การกดปุ่ม B จะเปลี่ยนโหมดการสุ่มตำแหน่งและอัปเดตไปเรื่อย ๆ (Auto mode) หรือ โหมดที่ต้องกดปุ่ม A เพื่อสุ่มตำแหน่งใหม่ในแต่ละครั้ง (Manual Mode) ในโค้ดตัวอย่างนี้ จะเห็นได้ว่า มีการสาธิตการใช้โครงสร้างข้อมูลในภาษาไพธอน อย่างเช่น เซต (Set) และอาร์เรย์สองมิติ (Two-dimensional Array)
โค้ดตัวอย่างที่ 4: การเอียงบอร์ดเพื่อทำให้ LED สว่างทุกดวง
ตัวอย่างถัดไปสาธิตการทำให้ LED สว่าง ทีละดวง เริ่มต้นจากดวงแรกที่พิกัด (2,2) ซึ่งอยู่ตรงกลางบอร์ด และมีการกระพริบที่ LED เพื่อระบุตำแหน่งพิกัดขณะนั้น
ถ้ามีการเอียงบอร์ดไปในทิศทางใด จะทำให้ตำแหน่งของ LED ที่กระพริบเปลี่ยนไป และ LED ในตำแหน่งก่อนหน้านั้น จะเปลี่ยนจาก OFF (0) เป็น ON (1) และจะเห็นว่า มีจำนวน LED ที่อยู่ในสถานะ ON เพิ่มมากขึ้น
เมื่อทำให้ LED ทุกดวงสว่างครบแล้ว (5*5 = 25 ดวง) โดยการเอียงบอร์ดตามแกนอ้างอิง x หรือ y จะเห็นได้ว่า หลังจากนั้น LED ทุกดวงกระพริบ ถ้าต้องการจะเริ่มต้นใหม่ ให้กดปุ่ม A
การตรวจสอบดูว่า มีการเอียงบอร์ดไปทางใด เราจะใช้คำสั่งของ accelerometer
เช่น get_x()
และ get_y()
อ่านค่าสำหรับแกน x และ y ถ้าวางบอร์ดในแนวราบ ค่าที่อ่านได้สำหรับแกน x และ y จะเข้าใกล้ 0 แต่
ถ้ามีการเอียงบอร์ดไปทางด้านหนึ่ง ค่าจะเพิ่มเป็นบวกมากขึ้น แต่ถ้าเอียงไปอีกด้านหนึ่งค่าจะลดลง ได้ค่าตัวเลขเป็นลบ (น้อยกว่า 0)
โค้ดตัวอย่างที่ 5: การกำหนดสีให้โมดูล RGB LED (WS2812 NeoPixel)
โมดูล RGB LED ที่ใช้ชิป WS2812B (SMD 5050) สามารถโปรแกรมค่าสีแบบ RGB (Red, Green, Blue) ได้ โดยกำหนดค่าในช่วง 0..255 สำหรับแต่ละสี
เราสามารถใช้คำสั่งจากไลบรารี neopixel สำหรับไมโครบิต โดยสามารถระบุได้ว่า จะใช้แถบ RGB LED จำนวนกี่ดวง หรือระบุตำแหน่งทั้งหมด ในตัวอย่างนี้ จะใช้เพียงหนึ่งตำแหน่ง (ดวงเดียว) โดยทำคำสั่ง NeoPixel(pin1, 1)
และเลือกใช้ขา P1 ต่อไปยังขาสัญญาณอินพุตควบคุมของโมดูล NeoPixel ที่มีเพียงหนึ่งพิกเซล RGB (หนึ่งตำแหน่ง)
การกำหนดค่าให้แต่ละตำแหน่งจะใช้ Tuple ที่มีข้อมูลตัวเลข 3 ตัว สำหรับ (R,B,G) ตามลำดับ เลือกสุ่มมาจากอาร์เรย์ values
โดยใช้คำสั่ง random.choice()
จากรูปภาพจะเห็นได้ว่า มีการใช้โมดูลของ Keyestudio นำมาต่อขาสำหรับ Edge Connector และมีขาแบบ Male Pin Headers การเชื่อมต่อทางไฟฟ้า ก็ใช้วิธีเสียบสายไฟ 3 เส้น เชื่อมต่อไปยังโมดูล NeoPixel (ควรตรวจสอบการต่อวงจรให้ถูกต้องก่อนเสียบสาย USB เพื่อจ่ายไฟให้บอร์ดไมโครบิต)
ข้อควรระวัง: ในการต่อวงจรเพื่อใช้งาน NeoPixel ร่วมกับบอร์ดไมโครบิต สามารถใช้แรงดันไฟเลี้ยง 3.3V จากบอร์ดไมโครบิตได้ แต่ถ้าต้องการจะใช้โมดูล NeoPixel แบบหลายตำแหน่ง (มี RGB LED หลายดวง) จะใช้ปริมาณกระแสมาก แนะนำให้ใช้แหล่งจ่ายไฟ DC 3.3V จากภายนอก และต่อ GND ของระบบร่วมกัน
โค้ดตัวอย่างที่ 6: การสร้างสัญญาณ PWM จำนวน 3 ช่องเอาต์พุต
ถัดไปเป็นการสาธิตการเขียนโค้ด เพื่อสร้างสัญญาณแบบ PWM (Pulse Width Modulation) ซึ่งเป็นสัญญาณรูปคลื่นสี่เหลี่ยมแบบมีคาบ (Periodic Rectangular Waveform) แต่สามารถปรับค่าความกว้างช่วงที่เป็น High Pulse (หรือเรียกว่า Duty Cycle) ได้ 0% ถึง 100%
บอร์ดไมโครบิต สามารถสร้างสัญญาณ PWM ที่กำหนดค่า Duty Cycle ได้ มีขนาดความละเอียด 10 บิต ซึ่งเป็นค่าในช่วง 0..1023 (Duty Cycle 0% .. 100%) และสามารถกำหนดคาบสัญญาณได้เช่นกัน (ต่ำสุดคือ 256 ไมโครวินาที) ถ้าเพิ่มคาบสัญญาณให้กว้างขึ้น ก็จะได้สัญญาณ PWM ที่มีความถี่ต่ำลง
ในตัวอย่างนี้ เราจะใช้คำสั่ง write_analog()
สำหรับ Microbit Pin สร้างสัญญาณ PWM และกำหนดให้มีความถี่ 500 Hz (มีคาบ 2 msec หรือ 2000 usec) จำนวน 3 ช่องสัญญาณ (ใช้ขา P0, P1, P2 เป็นเอาต์พุต) เพื่อนำไปขับวงจรหรือโมดูล RGB LED ทำให้เปลี่ยนสีได้
สัญญาณ PWM จำนวน 3 ช่อง จะถูกใช้ในการกำหนดค่าสีของโมดูล RGB LED นั้น ในโค้ดตัวอย่างได้กำหนดให้ค่า Duty Cycle ของแต่ละช่องสัญญาณเพิ่มขึ้นหรือลดลงตามรูปแบบของฟังก์ชัน cosine แบ่งเป็นทั้งหมด N=64 ระดับ และสเกลค่าให้อยู่ในช่วง 0..1023
ข้อสังเกต: โมดูล RGB LED ที่ได้เลือกนำมาใช้งานนั้น มีขา Pin Headers ได้แก่ V (VCC), R (Red), B (Blue), G (Green) ตามลำดับ และทำงานแบบ Active-Low
โค้ดตัวอย่างที่ 7: การอ่านค่าจากขาแอนะล็อกอินพุต
ถัดไปเป็นตัวอย่างการอ่านค่าจากขา P0 ที่สามารถใช้เป็นขาอินพุตแอนะล็อกได้ โดยนำมาใช้อ่านค่าจากโมดูล Key-Switch แบบแอนะล็อก (หรือ ADKeypad) หลักการทำงานของโมดูลประเภทนี้คือ เมื่อป้อนแรงดันไฟเลี้ยง VCC กับ GND แล้ว จะได้แรงดันไฟฟ้าที่ขาสัญญาณเอาต์พุตที่ขึ้นอยู่กับสถานะการกดปุ่ม (โดยทั่วไป ก็จะกดเพียงปุ่มเดียวในแต่ละช่วงเวลา)
โมดูลที่ได้เลือกมาใช้งาน มีทั้งหมด 5 ปุ่ม มีข้อความเขียนกำกับเอาไว้คือ SW1, SW2, ..., SW5 ถ้าอ่านค่าจากขา P0 แบบแอนะล็อก โดยใช้คำสั่ง read_analog()
จะได้ค่าในช่วง 0..1023 ซึ่งก็ขึ้นอยู่กับสถานะการกดปุ่ม และนำมาใช้ในการจำแนกหรือตรวจสอบดูว่า ปุ่มใดกำลังถูกกดอยู่ในขณะนั้น
ให้ทดลองอ่านค่าแล้วส่งออกมาทาง Serial ด้วยคำสั่ง print()
และทำซ้ำไปเรื่อย ๆ แล้วกดไปทีละปุ่ม เราจะเห็นค่าอินพุตที่อ่านได้สำหรับแต่ละกรณี ยกตัวอย่างเช่น ถ้ายังไม่กดปุ่มใด ๆ เลย ค่าที่อ่านได้จะอยู่ในช่วงประมาณ 800 ถึง 850 เป็นต้น
โค้ดตัวอย่างที่ 8: การตรวจสอบการใช้นิ้วสัมผัสที่ Touch Pad
ตัวอย่างนี้สาธิตการตรวจสอบดูว่า มีการใช้นิ้วสัมผัสที่บริเวณ Touch Pad 0 ของบอร์ดไมโครบิตหรือไม่ (และให้ใช้อีกนิ้วหนึ่ง สัมผัสที่ Pad GND ของบอร์ด) โดยใช้คำสั่ง pin0.is_touched()
ซึ่งจะได้ค่าแบบ boolean
ถ้ามีการสัมผัสด้วยนิ้วในแต่ละครั้งที่ขา P0 จะทำให้สถานะของ LED Display เปลี่ยนไป ซึ่งมีอยู่ 4 รูปแบบ หรือ ระดับ ดังนี้
ระดับที่ 1 เริ่มต้น ไม่มี LED อยู่ในสถานะ ON
ระดับที่ 2 มี LED เพียง 1ดวง (ตรงกลาง) ในสถานะ ON
ระดับที่ 3 มี LED จำนวน 3x3 ดวงในสถานะ ON
ระดับที่ 4 มี LED จำนวน 5x5 ดวง (ทุกดวง) ในสถานะ ON
โค้ดตัวอย่างที่ 9: การตรวจสอบการเชื่อมต่ออุปกรณ์ I2C Slave
บอร์ดไมโครบิต สามารถเชื่อมต่อกับอุปกรณ์อื่นในระบบบัส I2C ที่ใช้สายสัญาณเพียง 2 เส้นคือ SDA (Serial Data Line) และ SCL (Serial Clock Line) ไมโครบิตจะทำหน้าที่เป็นอุปกรณ์ I2C Master ซึ่งเป็นฝ่ายเริ่มต้น หรือควบคุมการทำงานของอุปกรณ์อีกฝ่ายหนึ่งคือ I2C Slave เช่น ต้องการจะเขียน (Write Operation) หรืออ่านข้อมูล (Read Operation) เป็นต้น นอกจากนั้นจะต้องมีการระบุแอดเดรสขนาด 7 บิต (7-bit Slave Address) ของอุปกรณ์แต่ละตัวในระบบบัสเดียวกัน
การเขียนโค้ดเพื่อใช้งานบัส I2C ก็มีคำสั่งในกลุ่ม i2c ไว้ให้ใช้งาน โดยทั่วไป เราก็ใช้ความเร็ว 100kHz หรือ 400kHz ในการสื่อสารสำหรับบัส I2C
บอร์ดไมโครบิตมีวงจรหรือไอซีที่เชื่อมต่อด้วยบัส I2C อยู่แล้ว ได้แก่ ไอซีวัดความเร่ง (Accelerometer IC) และไอซีเข็มทิศดิจิทัล (Digital Compass IC) เป็นต้น แต่ถ้าเราจะนำอุปกรณ์ I2C Slave ตัวอื่น มาต่อเพิ่ม ก็ให้เลือกใช้ขา Pin 20 และ Pin 19 ของบอร์ดไมโครบิต เป็นขาสัญญาณ SDA และ SCL ตามลำดับ และอุปกรณ์เหล่านั้นจะต้องทำงานที่แรงดันไฟฟ้า +3.3V เช่นกัน
ลองมาดูตัวอย่างการเขียนโค้ด เพื่อตรวจสอบหรือสแกนอุปกรณ์ (Device Scan) และแสดงหมายเลขแอดเดรส (ฐานสิบหก) ของอุปกรณ์ Slave Device ในระบบบัส I2C ของบอร์ดไมโครบิต ส่งเป็นข้อความออกทาง Serial โดยแบ่งเป็นสองวิธี
สร้างฟังก์ชัน
scan_i2c()
ที่เราสร้างขึ้นเองแล้วเรียกใช้ หรือเรียกใช้ฟังก์ชัน
i2c.scan()
ซึ่งมีไว้ให้แล้ว
ถ้าทำงานได้ถูกต้อง จะต้องพบอุปกรณ์หมายเลข 0x0e
(Compass) และ 0x1d
(Accelerometer) สำหรับบอร์ดไมโครบิตเวอร์ชัน 1.3B
โค้ดตัวอย่างที่ 10: การอ่านค่าจากโมดูลเซ็นเซอร์แสง BH1750
ตัวย่างถัดไปเป็นการอ่านข้อมูลจากโมดูลเซ็นเซอร์วัดแสง BH1750 (GY-302) ซึ่งจะให้ค่าที่มีความละเอียด 16 บิต (0..65535) หน่วยเป็นลักซ์ (Lux) เมื่อเริ่มต้นก่อนใช้งาน จะต้องส่งคำสั่งไปกำหนดโหมดการทำงานของ BH1750
ในตัวอย่างนี้ ได้ใช้โหมด Continuous Measurement ความละเอียด 1.0 Lux ต่อหนึ่งบิต (รายละเอียดเชิงเทคนิคเกี่ยวกับ BH1750 แนะนำให้ศึกษาจากเอกสาร Datasheet ของผู้ผลิต)
โมดูลที่นำมาใช้งานนั้น เชื่อมต่อแบบบัส I2C ใช้แรงดันไฟเลี้ยง 3.3V และมีหมายเลขแอดเดรสของอุปกรณ์คือ 0x23
(= 35 decimal) ซึ่งเป็น Default Address
โมดูลนี้มีขา ADDR ถ้าต่อขาดังกล่าวด้วยสายไฟไปยังขา VCC (3.3V) จะได้แอดเดรสเป็น 0x5C
(92 dec) แต่ถ้าต่อไปยังขา GND หรือปล่อยไว้ไม่ต้องต่อขา (Not Connected) จะได้แอดเดรสเป็น 0x23
(25 dec)
ตัวอย่างโค้ดนี้ จะอ่านข้อมูลจากโมดูลเซ็นเซอร์ทั้งหมด 10 ครั้ง ในแต่ละครั้งจะส่งข้อความแสดงค่าที่อ่านได้ออกทาง Serial โดยใช้คำสั่ง print()
โค้ดตัวอย่างที่ 11: การอ่านค่าและแสดงสถานะการทำงานของ Wii Nunchuk
โมดูล Wii Nunchuk เป็นอุปกรณ์เสริมที่ใช้ร่วมกับ Wii Remote ของ Nintendo แต่ก็สามารถนำมาใช้งานเพื่อต่อเข้ากับบอร์ดไมโครคอนโทลเลอร์ได้ โดยใช้วิธีสื่อสารแบบบัส I2C แต่จะต้องมี PCB Adapter ใช้ในการแปลงคอนเนกเตอร์ให้เป็นแบบ Pin Headers (หรือจะดัดแปลงสายไฟและเปลี่ยนชนิดของคอนเนกเตอร์ใหม่ก็ได้)
อุปกรณ์ใช้หมายเลขแอดเดรสเท่ากับ 0x52
และรูปแบบข้อมูลที่ได้จากอุปกรณ์นี้ (อ่านคราวละ 6 ไบต์) ได้ถูกกำหนดไว้โดยผู้ผลิต แนะนำให้ลองสืบค้นดูในอินเทอร์เน็ตและศึกษาจากแหล่งข้อมูลอื่นที่ได้อธิบายหรือระบุความหมายข้อมูลไบต์แต่ละตำแหน่ง
โดยสรุป ข้อมูลไบต์ที่อ่านได้ มีดังนี้
ไบต์แรกและไบต์ที่สอง เป็นค่าของคันโยกควบคุม (Joystick) ในแกน x และแกน y ตามลำดับ ถ้าอยู่ในตำแหน่งตรงกลาง จะได้ค่าใกล้เคียง 127
สามไบต์ถัดไปคือ ค่าที่ได้จากตัววัดความเร่ง 3 แกน คือ แกน x, y และ z ตามลำดับ อย่างละหนึ่งไบต์
ไบต์ที่หกเป็นตัวระบุสถานะของปุ่มกด C (บิตที่ 1) และ Z (บิตที่ 0) ถ้าบิตมีค่าเป็น 0 หมายความว่า ปุ่มที่เกี่ยวข้องกับบิตดังกล่าว กำลังถูกกดอยู่ในขณะนั้น
โค้ดตัวอย่างนี้ สาธิตการอ่านค่าจาก Wii Nunchuk มีดังนี้
จากโค้ดตัวอย่างนี้ เราสามารถนำไปประยุกต์ใช้ในการเล่นหรือควบคุมเกมคอมพิวเตอร์ เช่น ใช้คันโยกแกน X และ Y รวมถึงปุ่มกด C และ Z เป็นต้น
โค้ดตัวอย่างที่ 12: การอ่านค่าจากโมดูลเซ็นเซอร์ SHT31
โค้ดในตัวอย่างนี้ สาธิตการอ่านค่าจากโมดูลเซ็นเซอร์ SHT31-DIS สำหรับวัดอุณหภูมิและความชื้นสัมพัทธ์ (ใช้ไอซีที่ผลิตโดยบริษัท SENSIRION) และแสดงค่าที่อ่านได้เป็นข้อความเอาต์พุตทาง Serial โดยใช้คำสั่ง print()
ในโค้ดตัวอย่างนี้ มีการสร้างออบเจ็กต์จากคลาส SHT3x
ที่ได้มีการสร้างไว้ในไฟล์ sht3x.py และสามารถเรียกใช้คำสั่ง measure()
เพื่อสั่งตัวเซ็นเซอร์ให้อัปเดตค่าครั้งถัดไป และใช้คำสั่ง read()
เพื่ออ่านค่าตัวเลขสำหรับอุณหภูมิและความชื้นสัมพัทธ์
โค้ดอีกหนึ่งไฟล์ (sht3x.py) ที่จะต้องนำไปบันทึกลงใน Flash Storage ของไมโครบิต เพื่อใช้ร่วมกับโค้ดตัวอย่างข้างบน มีดังนี้
สำหรับการทดลองต่อวงจร โมดูลนี้ใช้แรงดันไฟเลี้ยงที่ 3.3V จากบอร์ดไมโครบิตได้ การเชื่อมต่อกับโมดูลเซ็นเซอร์ SHT31-DIS ใช้วิธี I2C Bus ที่มีสายสัญญาณ 2 เส้น SCL และ SDA (ขา SCL และ SDA นำไปต่อกับขา P19 และ P20 ของบอร์ดไมโครบิตตามลำดับ) และมีการกำหนดแอดเดรสไว้เท่ากับ 0x44
แนะนำให้ใช้โปรแกรม Mu Editor ในการเขียนโค้ด แล้วให้กดปุ่มไอคอน Files จะมีการแสดงรายการแบ่งเป็น 2 กลุ่ม (แบ่งเป็นด้านซ้ายกับขวามือ) เราสามารถเลือกไฟล์จากกลุ่มหนึ่ง ลากไปวาง (Drag & Drop) ใส่อีกกลุ่มหนึ่ง ซึ่งเป็นการสำเนาไฟล์ที่เลือก ระหว่างคอมพิวเตอร์กับอุปกรณ์ไมโครบิต
ลำดับขั้นตอนการทดสอบโค้ดกับบอร์ดไมโครบิตโดยใช้ Mu Editor
สร้างไฟล์ใหม่ โดยกดปุ่ม New แล้วเขียนโค้ดตามตัวอย่างและบันทึกลงในไฟล์ชื่อ sht3x.py ในคอมพิวเตอร์ของผู้ใช้
กดปุ่ม Files แล้วเลือกไฟล์ sht3x.py จากรายการไฟล์ในคอมพิวเตอร์ของผู้ใช้ แล้วลากไปยังบอร์ดไมโครบิต (Drag & Drop เพื่อสำเนาไฟล์)
เขียนโค้ดตัวอย่าง main.py แล้วอัปโหลดไปยังบอร์ดไมโครบิต โดยกดปุ่ม Flash แล้วจึงกดปุ่ม REPL
ในบริเวณช่องรับคำสั่งของ REPL ให้กดปุ่มบนแป้นพิมพ์ Ctrl+D เพื่อเริ่มต้นการทำงานของไมโครไพธอนใหม่อีกครั้ง และรันโค้ด main.py โดยอัตโนมัติ
สังเกตข้อความเอาต์พุตที่ปรากฏในบริเวณ REPL
ข้อสังเกต: ในโปรแกรม Mu Editor (v1.1.0alpha2) การเลือกทำคำสั่งจากปุ่มไอคอน Flash, Files และ REPL จะทำพร้อมกันไม่ได้ จะต้องเลือกอย่างใดอย่างหนึ่งในแต่ละช่วงเวลา เช่น ถ้าเปิดใช้ REPL อยู่ในขณะนั้น จะไม่สามารถทำขั้นตอน Flash หรือ Files ได้
โค้ดตัวอย่างที่ 13: SHT31 + I2C 16x2 LCD
โค้ดตัวอย่างนี้สาธิตการใช้งานโมดูล 16x2 LCD (แสดงผลข้อความแบบ Alphanumeric มี 2 แถว ๆ ละ 16 ตัวอักษร) แบบ I2C ที่ใช้ไอซี PCF8574 เป็นตัวควบคุมการทำงาน และอ่านค่าจากโมดูลเซ็นเซอร์ SHT31 ผ่านทาง I2C เช่นเดียวกันแล้วนำค่าที่ได้มาแสดงเป็นข้อความบนจอโมดูล LCD
โมดูล SHT31 มีการกำหนดแอดเดรสไว้เท่ากับ 0x44
ในขณะที่โมดูล 16x2 LCD-PCF8574 มีแอดเดรสเท่ากับ 0x3F
โค้ดไมโครไพธอนสำหรับไฟล์ lcd_pcf8574.py มีดังนี้
โค้ดตัวอย่างที่ 14: การสร้างรูปกราฟิกบน LED Matrix
โค้ดตัวอย่างต่อไปนี้ สาธิตการสร้างรูปกราฟิกตามรูปแบบที่กำหนดโดยเงื่อนไข โดยใช้ค่าของพิกัด (x,y) บนแผง 5x5 LED Matrix (N=5)
ฟังก์ชัน create_pattern(..)
ใช้สำหรับสร้างข้อมูลอาร์เรย์ data
ที่มีข้อมูลสมาชิกเป็น 0 หรือ 1 และมีจำนวนเท่ากับ 5x5 (25) ค่าของอาร์กิวเมนต์ i
สำหรับฟังก์ชันนี้ เป็นเลขจำนวนเต็ม i=0,1,...,6
จะเป็นตัวเลือกว่า ต้องการสร้างข้อมูลในอาร์เรย์เป็นแบบใด
ฟังก์ชัน conditions(..)
ทำหน้าที่ระบุสถานะที่พิกัด (x,y) ของ LED Matrix ตามเงื่อนไขที่กำหนดไว้ และ i
เป็นอาร์กิวเมนต์ เพื่อกำหนดรูปแบบ หรือ กรณีในการสร้างรูปกราฟิก ฟังก์ชันนี้จะถูกเรียกใช้ในฟังก์ชัน create_pattern(..)
ฟังก์ชัน show_pattern(..)
ใช้สำหรับนำค่าที่ได้จากอาร์เรย์ data
ไปใช้เพื่อแสดงสถานะของ LED Matrix บนบอร์ดไมโครบิต ถ้ามีสถานะเป็น 0 หมายถึง OFF แต่ถ้ามีค่าเท่ากับ 1 หมายถึง ON (มีค่าของความสว่าง 9)
เมื่อทดสอบการทำงานของโค้ด ให้กดปุ่ม A เพื่อเปลี่ยนรูปแบบกราฟิกในลำดับถัดไป
โค้ดตัวอย่างที่ 15: Conway's Game of Life
โค้ดตัวอย่างถัดไป สาธิตการจำลองสถานการณ์ที่เรียกว่า Conway's Game of Life ซึ่งกล่าวถึง ระบบที่ประกอบด้วยเซลล์ (Cells) ที่ถูกจัดเรียงแบบเมตริกซ์ (อาร์เรย์สองมิติ) แต่ละเซลล์ที่พิกัด (x,y) มีสถานะเป็น 0 หรือ 1 ซึ่ง 0 หมายถึง ไม่มีชีวิต (dead) และ 1 หมายถึง เซลล์กำลังมีชีวิตอยู่ (alive)
สถานะเริ่มต้นของเซลล์ อาจได้จากการสุ่ม (Randomization of Cell States) และสถานะของเซลล์ที่เปลี่ยนแปลงไปตามเวลา (เวลาเป็นแบบ discrete-time) ขึ้นอยู่กับสถานะของเซลล์โดยรอบ (Neighbouring Cells) โดยทั่วไปแต่ละเซลล์ในอาร์เรย์สองมิติ จะมีเซลล์ที่อยู่รอบ ๆ ติดกัน ไม่เกิน 8 เซลล์ (มีอยู่รอบทิศ)
การกำหนดสถานะของเซลล์ในลำดับเวลาถัดไป เป็นไปตามกฎ (Rules) ได้ดังนี้
ถ้าเซลล์นั้นมีชีวิต และมีจำนวนเซลล์รอบ ๆ ที่มีชีวิตอยู่ เท่ากับ 2 หรือ 3 ให้เซลล์นั้นยังคงมีชีวิตต่อไป (Healthy Population)
ถ้าเซลล์นั้นมีชีวิต แต่มีจำนวนเซลล์รอบ ๆ ที่มีชีวิตอยู่ น้อยกว่า 2 หรือ มากกว่า 3 ให้เซลล์นั้นตายไป (กรณีนี้เรียกว่า Underpopulation และ Overpopulation ตามลำดับ)
ถ้าเซลล์นั้นไม่มีชีวิตหรือตายไปแล้ว แต่มีจำนวนเซลล์รอบ ๆ ที่มีชีวิตอยู่ เท่ากับ 3 ให้เซลล์นั้นเริ่มต้นหรือกลับมามีชีวิตใหม่อีกครั้ง (กรณีนี้เรียกว่า Reproduction)
ในโค้ดตัวอย่างนี้ ขนาดของเมตริกซ์เท่ากับ 5x5 (N=5) แต่การเก็บสถานะของเซลล์ จะใช้อาร์เรย์มิติเดียว (One-dimensional Array หรือ List) โดยใช้ชื่อตัวแปรว่า cells
ดังนั้นสถานะของเซลล์ที่พิกัด (x,y) ในอาร์เรย์ดังกล่าวคือ cells[x + N*y]
ตัวอย่างการเขียนโค้ดเพื่อสาธิต Conway's Game of Life ด้วย MakeCode Static TypeScript สำหรับบอร์ดไมโครบิต สามารถศึกษาได้จาก https://makecode.microbit.org/examples/gameofLife
โค้ดตัวอย่างที่ 16: การวัดความกว้างของสัญญาณพัลส์
โค้ดตัวอย่างนี้ สาธิตการวัดความกว้างของสัญญาณบแบบพัลส์ (Pulse) เช่น สัญญาณประเภท PWM (Pulse Width Modulation) เช่น ถ้าเราต้องการทราบความกว้างของพัลส์ช่วงที่เป็นลอจิก 1 (High) เราจะสามารถใช้บอร์ดไมโครบิตวัดค่าได้หรือไม่
ตัวอย่างนี้สร้างสัญญาณ PWM ที่ความถี่ 50Hz หรือ มีความกว้าง 20 msec เป็นสัญญาณแบบ PWM โดยเลือกใช้ขา pin8
และใช้คำสั่ง write_analog()
ซึ่งจะต้องระบุค่าตัวเลข (ขนาด 10 บิต) ในช่วง 0..1023 (หรือเท่ากับ 0% .. 100% สำหรับค่า Duty Cycle ของสัญญาณดังกล่าว)
ถ้ากำหนดให้ Duty Cycle = 25% 50% และ 75% โดยทางทฤษฏี จะได้ความกว้างเท่ากับ 5000, 10000 และ 15000 ไมโครวินาที ตามลำดับ
สัญญาณเอาต์พุตที่ขา pin8
จะถูกป้อนกลับเข้าที่ขา pin11
ซึ่งถูกใช้เป็นขาอินพุต-ดิจิทัล (ในการทดลอง สามารถใช้ลวดสายไฟ Jumper Wire เชื่อมต่อระหว่างขาทั้งสอง)
การวัดความกว้างของพัลส์ช่วงที่เป็น 1 สามารถทำได้ง่ายโดยใช้คำสั่ง time_pulse_us()
ของกลุ่มคำสั่ง machine
การเรียกใช้คำสั่งนี้ จะต้องระบุขา (Pin) ที่ต้องการใช้ เลือกประเภทของพัลส์เป็น High (1) หรือ Low (0) และกำหนดค่าตัวเลขสำหรับ Timeout (หน่วยเป็นไมโครวินาที)
โค้ดตัวอย่างที่ 17: การวัดระยะห่างจากสิ่งกีดขวางโดยใช้โมดูล Ultrasonic Sensor HC-SR04P
HC-SR04P เป็นโมดูลเซ็นเซอร์ที่ใช้สัญญาณคลื่นเสียงอัลตราโซนิค (ความถี่สูง ประมาณ 40kHz) ในการตรวจสอบและวัดระยะห่างจากวัดถุกีดขวาง
หลักการทำงานของเซ็นเซอร์ประเภทนี้คือ การใช้ตัวส่ง (Transmitter) สร้างสัญญาณที่เป็นคลื่นเสียงออกไป เมื่อไปกระทบวัตถุ จะเกิดคลื่นสะท้อนกลับมายังตัวรับ (Receiver) เมื่อจับเวลาการเดินทางของคลื่นเสียงในทิศทางไปและกลับ และกำหนดอัตราเร็วของคลื่นเสียงในอากาศ (เช่น 340 เมตร/วินาที โดยประมาณ) ก็จะสามารถคำนวณระยะห่างจากวัตถุได้
โมดูล HC-SR04P สามารถวัดระยะห่างจากวัตถุได้สูงสุด ประมาณ 4 เมตร และใช้แรงดันไฟเลี้ยง 3.3V หรือ 5V ได้ โมดูลนี้มีขาอินพุต TRIG (Trigger) และขาเอาต์พุต ECHO เมื่อได้รับสัญญาณพัลส์ (ความกว้างอย่างน้อย 10 ไมโครวินาที) ที่ขา TRIG จะมีการสร้างสัญญาณคลื่นเสียงออกไป หลังจากนั้นจะเกิดสัญญาณพัลส์ที่ขา ECHO ความกว้างของสัญญาณพัลส์ที่ขา ECHO จะเป็นตัวระบุระยะเวลาการเดินทางของคลื่นเสียงและสะท้อนกลับมาถึงตัวรับ
การวัดความกว้างของพัลส์ ก็ทำได้ง่าย โดยใช้คำสั่ง time_pulse_us()
ในชุดคำสั่ง machine
จากนั้นจะต้องแปลงค่าที่ได้วัดได้สำหรับระยะเวลา (มีหน่วยเป็นไมโครวินาที) ให้เป็นระยะทาง (มีหน่วยเป็นเซนติเมตร)
โค้ดตัวอย่างนี้เลือกใช้ขา pin12
สำหรับสัญญาณ ECHO และ pin13
สำหรับ TRIG ตามลำดับ โดยจะทำการวัดค่าที่เป็นระยะห่างจากวัตถุซ้ำไปเรื่อย ๆ จนกว่าจะหยุดเมื่อมีการกดปุ่ม Button A
โค้ดตัวอย่างที่ 18: การใช้งานไอซี MCP4921 SPI DAC
MCP4921 ของบริษัท Microchip เป็นไอซีประเภท DAC (Digital-to-Analog Converter) มีเพียงเอาต์พุต 1 ช่องสัญญาณ (แต่ถ้าเป็น MCP4922 จะมี 2 ช่อง) มีความละเอียดของข้อมูล เท่ากับ 12 บิต (4096 ระดับ) และรับข้อมูลโดยใช้บัส SPI
ตัวอย่างนี้ สาธิตการสร้างสัญญาณรูปไซน์ (Sinusoidal Waveform) หนึ่งคาบ โดยใช้ไอซี MCP4921 DAC สร้างสัญญาณเอาต์พุตแบบแอนะล็อก ใช้แรงดันไฟเลี้ยงและแรงดันอ้างอิง (Reference Voltage) เท่ากับ +3.3V
ถ้าจะลองต่อวงจรบนเบรดบอร์ด ก็ให้ใช้ตัวถังของไอซีแบบ PDIP-8 มี 8 ขา ดังนี้
VDD เป็นขาแรงดันไฟเลี้ยง
/CS เป็นขาสัญญาณอินพุต Chip-Select ทำงานแบบ Active-Low
SCK เป็นขาสัญญาณอินพุต Serial Clock Input (ความถี่สูงสุดที่ใช้ได้คือ 20MHz)
SDI เป็นขาอินพุตสำหรับข้อมูลที่เลื่อนเข้าทีละบิต Serial Data Input
/LDAC เป็นขาอินพุตสำหรับสัญญาณควบคุม DAC Ouput Latch ทำงานแบบ Active-Low โดยทั่วไป ให้ต่อกับ GND ของวงจร เพื่อให้เอาต์พุตที่การเปลี่ยนแปลงโดยอัตโนมัติหลังจากเขียนข้อมูล 16 บิต (เมื่อ /CS เปลี่ยนจาก LOW เป็น HIGH)
VREFA เป็นขาแรงดันไฟฟ้าอ้างอิงสำหรับการสร้างสัญญาณแบบแอนะล็อก
AVSS เป็นขา Ground (GND)
VOUTA เป็นขาสัญญาณเอาต์พุตแบบแอนะล็อก (DAC Output)
การเขียนข้อมูลไปยัง MCP4921 มีครั้งละ 2 ไบต์ สำหรับข้อมูล 16 บิต (ส่งข้อมูลบิตที่ 15..8 และบิตที่ 7..0 ตามลำดับ) ส่งผ่านบัส SPI ไมโครบิตทำหน้าที่เป็น SPI Master และไอซี MCP4921 เป็น SPI Slave เลือกใช้โหมดการทำงานของ SPI เป็น (CPOL=1, CPHA=1) หรือโหมด 3 และลองใช้ความถี่ เช่น 1MHz
ข้อมูล 16 บิต มีการแบ่งออกเป็น 2 ส่วน คือ ส่วนแรกมี 4 บิต เรียกว่า Config Bits และส่วนที่สองมี 12 บิต เรียกว่า Data Bits ซึ่งเป็นตัวกำหนดระดับแรงดันเอาต์พุตที่ขา VOUTA
กลุ่มคำสั่งที่เกี่ยวข้องกับการใช้งานบัส SPI คือ machine.spi
และเริ่มต้นโดยการใช้คำสั่ง spi.init()
ซึ่งมีอาร์กิวเมนต์ดังนี้
ความเร็วในการส่งข้อมูล (baudrate)
ขนาดข้อมูลหนึ่งเฟรม (bits = จำนวนบิตในการเลื่อนข้อมูล) เช่น 8 บิต
โหมดการทำงานของ SPI ที่ต้องการเลือกใช้งาน เลือกโหมด (0,0) หรือ (1,1)
ขา GPIO ที่ใช้งานสำหรับสัญญาณ SCK (Serial Clock), MOSI (Master-Out / Slave-In) และ MISO (Master-In / Slave-Out) ของบัส SPI
ถ้าต้องการส่งข้อมูลออกไป ก็ใช้คำสั่ง spi.write()
ซึ่งจะต้องระบุอาร์กิวเมนต์ที่เป็นบัฟเฟอร์ข้อมูล เช่น มีชนิดข้อมูลเป็น bytearray
และมีขนาดหรือความยาวตามจำนวนไบต์ที่ต้องการส่ง
อ้างอิงจากเอกสาร Datasheet ของ MCP4921 ขาเอาต์พุต VOUTA สามารถจ่ายหรือรับกระแสได้ไม่เกิน 25mA ดังนั้น ถ้าต่อวงจร LED อนุกรมกับตัวต้านทานจำกัดกระแส เช่น 330 โอห์ม ที่ขาเอาต์พุตดังกล่าว ก็สามารถสังเกตการเปลี่ยนแปลงของระดับแรงดันไฟฟ้าได้ (ซึ่งจะส่งผลต่อความสว่างของ LED) ในกรณีที่ไม่มีเครื่องวัดคลื่นสัญญาณ เช่น ออสซิลโลสโคป
โค้ดตัวอย่างที่ 19: การใช้ไอซี PCF8574 แสดงสถานะลอจิกของโมดูล LED ที่มี 8 ดวง
ตัวอย่างนี้ เป็นการแสดงสถานะติดหรือดับ (ON หรือ OFF) สำหรับโมดูล LED Bar ที่มี 8 ดวง โดยใช้ไอซี PCF8574 (8-bit I/O Expander) เป็นตัวกำหนดสถานะเอาต์พุต 8 บิต (ในตัวอย่างนี้ PCF8574 ทำงานในโหมดเอาต์พุตเท่านั้น)
โมดูลหรือไอซี PCF8574 ใช้วิธีสื่อสารข้อมูลกับไมโครบิตได้ด้วยบัส I2C และในตัวอย่างนี้ได้กำหนดให้โมดูลนี้ มีแอดเดรสเท่ากับ 0x20
และในการเชื่อมต่อสายกับไมโครบิต ก็ได้ใช้ขา pin19
และ pin20
สำหรับสัญญาณ SCL และ SDA ของบัส I2C ตามลำดับ
ไมโครบิตทำหน้าที่เป็น I2C Master และโมดูล PCF8574 ทำหน้าที่เป็น I2C Slave คอยรับข้อมูลหนึ่งไบต์ เพื่อนำมากำหนดสถาะลอจิกสำหรับเอาต์พุต 8 บิต ที่นำไปต่อกับโมดูล 8-Bit LED Bar
ข้อสังเกต: โมดูล LED Bar ที่ได้เลือกมาใช้งานนั้น มีขาอินพุต-ดิจิทัล 8 ขา LED0 .. LED7 ใช้กำหนดสถานะของ LED แต่ละดวง ทำงานแบบ Active-Low และมีขา VCC สำหรับป้อนแรงดันไฟเลี้ยง (ใช้ 3.3V)
เมื่อทดสอบการทำงานของโค้ดกับอุปกรณ์จริง จะเห็นได้ว่า จะมีเพียง LED หนึ่งดวงในแต่ละช่วงเวลา ที่อยู่ในสถานะ ON (สว่าง) และตำแหน่งของ LED ที่สว่าง จะถูกเลื่อนไปเรื่อย ๆ แล้ววนซ้ำใหม่
ข้อสังเกต: โมดูล PCF8574(A) ที่ได้เลือกมาใช้งานนั้น มีขา A2..A0 สำหรับเอาไว้กำหนดค่าบิตของแอดเดรส ดังนั้นแต่ละอุปกรณ์จึงมีแอดเดรสแตกต่างกันได้ในบัสเดียวกัน ในรูปตัวอย่าง มีการใช้ Jumper (สีเหลือง 3 อัน) กำหนดค่าบิตเป็น 0 หรือ 1 ให้กับขา A2..A0
โค้ดตัวอย่างที่ 20: การกำหนดสถานะลอจิกของโมดูล LED ที่มี 8 ดวง โดยใช้ค่าอินพุตแอนะล็อก
ตัวอย่างนี้สาธิตการอ่านค่าจากโมดูลที่มีตัวต้านทานปรับค่าและเลื่อนตำแหน่งได้แบบเชิงเส้น (Linear Potentiometer) โดยนำมาใช้เป็นวงจรแบ่งแรงดัน (Voltage Divider) ใช้แรงดันไฟเลี้ยง 3.3V และเลือกใช้ขา pin0
สำหรับอ่านค่าแรงดันอินพุต (อยู่ในช่วง 0V ถึง 3.3V) ที่ได้จากวงจรแบ่งแรงดันดังกล่าว
ค่าที่อ่านได้จากขาอินพุต pin0
จะอยู่ในช่วง 0..1023 (เนื่องจาก ADC มีความละเอียด 10 บิต) แต่จะถูกนำมาแปลงให้เป็นเลขจำนวนเต็ม ให้มีค่าอยู่ในช่วง 0..9 และเก็บไว้ในตัวแปร value
จากนั้นจะนำไปใช้กำหนดสถานะการทำงานของโมดูล LED Bar ที่มีจำนวน 8 ดวง
ค่าของตัวแปร value
จะถูกใช้ในการกำหนดจำนวนหรือระดับของ LED ที่อยู่ในสถานะ ON เช่น ถ้า value
มีค่าเท่ากับ 0 ซึ่งเป็นค่าต่ำสุด ก็จะไม่มีดวงใด LED สว่าง หรือถ้าใช้ค่าสูงสุดคือ 9 จะทำให้ LED ทุกดวงสว่าง เป็นต้น
โค้ดตัวอย่างที่ 21: การใช้โมดูล Rotary Encoder เป็นอุปกรณ์อินพุต
โดยทั่วไปแล้ว โมดูล Rotary Encoder มีขาสัญญาณเอาต์พุต A และ B (หรือเรียกแบบอื่น เช่น CLK กับ DT ตามลำดับ) และมีหลักการทำงานเหมือนสวิตช์ปุ่มกดคือ สถานะปรกติเป็น High (H) แต่เป็น Low (L) ถ้ามีการกดสวิตช์ในช่วงเวลาหนึ่ง
โดยปรกติขาสัญญาณ A และ B ของโมดูล Rotary Encoder มีสถานะเป็นลอจิก High (H) แต่เมื่อมีการหมุนในทิศทางตามหรือทวนเข็มนาฬิกา จะทำให้เกิดสัญญาณแบบ Pulse ที่ขา A และ B กล่าวคือ มีการเปลี่ยนจาก H->L (ขอบขาลง) หรือ L->H (ขอบขาขึ้น) ที่เกิดขึ้นตามสเต็ปการหมุน แต่ทั้งสองสัญญาณ A และ B จะมีเฟสต่างกัน (ขอบขาขึ้นหรือขาลง เกิดขึ้นไม่พร้อมกันทั้งสองสัญญาณ)
โค้ดตัวอย่างนี้ สาธิตการตรวจสอบดูว่ามีการหมุนเกิดขึ้นหรือไม่ โดยดูจากสัญญาณพัลส์ที่ขา A เกิดพัลส์แบบ High และมีความกว้าง (Pulse Width) ตามเงื่อนไขที่กำหนดไว้หรือไม่ จำนวนพัลส์ที่เกิดขึ้นขึ้นอยู่กับจำนวนสเต็ปที่หมุนไป
เมื่อเกิดพัลส์ที่สัญญาณ A ก็ตรวจสอบดูด้วยว่า สถานะลอจิกของสัญญาณ B เป็นอย่างไร เพื่อจำแนกว่า เป็นการหมุนในทิศทางใด เช่น ถ้าให้ทิศทางการหมุนเป็นตัวกำหนดว่า จะเพิ่มหรือลดค่าของตัวแปร level
ที่เป็นเลขจำนวนเต็ม และให้ตัวแปร level
ถูกจำกัดให้มีค่าอยู่ในช่วง 0 ถึง 9 เท่านั้น
ในตัวอย่างนี้ ได้ใช้โมดูล WS2812 Neopixel เพื่อใช้ RGB LED จำนวน 8 ดวง แสดงค่าของตัวแปร level
ในขณะนั้น ค่าของตัวแปร level
เป็นตัวกำหนดว่า จะมี LED ทั้งหมดกี่ดวงที่อยู่ในสถานะ ON (สว่าง)
ขา pin16
ของไมโครบิต ได้ถูกเลือกใช้เป็นขาเอาต์พุตสำหรับขา DIN ของโมดูล Neopixel และใช้แรงดันไฟเลี้ยง +3.3V จากโมดูลเสริมที่นำมาต่อกับ Edge Connector ของบอร์ดไมโครบิต
โค้ดตัวอย่างที่ 22: การรับส่งข้อมูลแบบ UART Loopback
บอร์ดไมโครบิตสามารถสื่อสารแบบ Serial กับอุปกรณ์อื่นได้ เนื่องจากมีวงจร UART อยู่ภายใน nRF51822 โดยจะต้องเลือกใช้ขา Pin จำนวน 2 ขา สำหรับใข้งานเป็นขา TXD (ส่งข้อมูลออก) และ RXD (รับข้อมูลเข้ามา)
โค้ดตัวอย่างนี้ สาธิตการใช้อุปกรณ์หรือโมดูล USB-to-Serial (ทำงานที่ระดับ +3.3V และใช้ไฟเลี้ยงจากพอร์ต USB) นำมาต่อเข้ากับขา pin0
และ pin1
เพื่อใช้เป็นขา TXD และ RXD ตามลำดับ และคอยรับข้อความจากคอมพิวเตอร์ของผู้ใช้ จากนั้นเมื่อได้รับแล้วก็ส่งข้อความนั้นกลับไป ดังนั้นจึงเป็นการทดสอบการใช้งานในรูปแบบที่เรียกว่า UART Loopback แต่ถ้าได้รับข้อความว่า 'exit'
หรือกดปุ่ม Button A ของบอร์ดไมโครบิต จะจบการทำงานของโปรแกรม
Microbit Pin | USB-to-Serial Pin |
pin0 (TXD) | RX |
pin1 (RXD) | TX |
GND | GND |
โปรแกรมสำหรับคอมพิวเตอร์ของผู้ใช้ที่ได้นำมาใช้ตัวอย่างนี้คือ Arduino IDE - Serial Monitor เช่น ส่งข้อความและรับข้อความตอบกลับจากไมโครบิตได้ (ตั้งค่า Baudrate ให้ตรงกับ 9600 สำหรับตัวอย่างนี้)
ข้อสังเกต: โดยปรกติ วงจร UART จะถูกใช้ในการสื่อสารกับ REPL ของไมโครไพธอน แต่หลังจากได้ใช้คำสั่ง uart.init()
ที่มีการระบุขาสำหรับ TXD และ RXD และกำหนดค่า Baudrate หรือความเร็วในการรับส่งข้อมูลแล้ว จะไม่สามารถสื่อสารผ่านทาง REPL Console ได้ต่อไป แต่ถ้าจะกลับไปสื่อสารกับ REPL Console ได้อีกครั้ง ก็ให้ทำคำสั่งดังนี้
โค้ดตัวอย่างที่ 23: การอ่านค่าจาก Analog Input แล้วส่งออกทาง UART
โค้ดตัวอย่างถัดไป สาธิตการอ่านค่าจากขาอินพุตแบบแอนะล็อก (Analog Input) ของบอร์ดไมโครบิต โดยเลือกใช้ขา pin2
และได้รับสัญญาณอินพุตจากโมดูลเซ็นเซอร์วัดความชื้นในดินแบบคาปาซิทีฟ (Capacitive Soil Moisture Sensor) แล้วนำค่าที่อ่านได้ (อยู่ในช่วง 0 ถึง1023) ส่งออกเป็นข้อความผ่านทาง UART โดยเลือกใช้ขาภายนอก pin0
และ pin1
สำหรับ TXD และ RXD ตามลำดับ
โมดูลเซ็นเซอร์วัดความชื้นในดินที่ได้เลือกมาลองใช้งาน จะตอบสนองต่อระดับความชื้นในดินดังนี้ ถ้ามีความชื้นมาก หรือมีปริมาณน้ำมาก หรือนำไปจุ่มน้ำในระดับหนึ่ง จะได้แรงดันไฟฟ้าที่ลดลง หรืออ่านค่าตัวเลขได้น้อยลง
ข้อความที่ถูกส่งออกไปนั้น จะมีหนึ่งค่าตัวเลขต่อหนึ่งบรรทัด และถ้าใช้โปรแกร Arduino IDE - Serial Plotter ก็จะเห็นกราฟเชิงเส้นจากข้อมูลที่ได้รับมาตามลำดับ
จากรูปกราฟตัวอย่างที่ได้จากการทดลอง สังเกตได้ว่า มีช่วงเวลาหนึ่งที่ค่าตัวเลขลดต่ำลงอย่างรวดเร็วแล้วเพิ่มขึ้น ซึ่งเกิดขึ้นเนื่องจากได้มีการเทน้ำในช่วงเวลาสั้น ๆ ลงในกระถางบริเวณที่มีแท่งวัดของโมดูลเซ็นเซอร์เสียบอยู่ในดิน
คำเตือน: การนำอุปกรณ์มาทดลองใช้งานนั้น เป็นไปเพื่อการสาธิตการทำงานของโค้ดตัวอย่างเท่านั้น ไม่เหมาะกับการนำไปใช้งานจริง ในสภาพแวดล้อมทั่วไป
โค้ดตัวอย่างที่ 24: การตรวจสอบปริมาณการใช้หน่วยความจำแบบ Heap
เมื่อมีการทำคำสั่งต่าง ๆ สร้างตัวแปรและอ็อปเจกต์สำหรับไมโครไพธอน จะมีการใช้หน่วยความจำ SRAM ของระบบที่ถูกจัดสรรไว้และเรียกว่า Heap ('ฮีป') ถ้าอ็อปเจกต์ใด ไม่ถูกอ้างอิงโดยตัวแปรหรือใช้งานอีกต่อไป เช่น โดยการใช้คำสั่ง del
จะเป็นหน้าที่ของส่วนที่เรียกว่า Garbage Collector เพื่อจัดการและคืนหน่วยความจำ
โค้ดตัวอย่างนี้ สาธิตการใช้คำสั่งเพื่อตรวจสอบสถานะการใช้หน่วยความจำสำหรับ Heap และเรียกใช้ Garbage Collector (gc
) ของไมโครไพธอน
มาดูผลการรันโค้ดและความแตกต่างระหว่างการใช้โปรแกรม Mu Editor และ Thonny IDE ตามลำดับ
เฟิร์มแวร์สำหรับไมโครไพธอนที่ใช้คือ
ถ้าใช้ Mu-Editor v1.0.2 จะได้ข้อความเอาต์พุตดังนี้
แต่ถ้าใช้ Thonny IDE v3.2.6 จะเป็นดังนี้
เราจะสังเกตเห็นความแตกต่างของปริมาณหน่วยความจำที่ใช้
โค้ดตัวอย่างที่ 25: การอ่านและแสดงค่าจากโมดูล SDS011 Dust Sensor
SDS011 เป็นโมดูลเซ็นเซอร์ราคาถูก ประเภท Air Quality Sensor / Laser Dust Sensor ที่ได้มีการพัฒนาโดยบริษัท Nova Fitness Co.Ltd. ในประเทศจีน สามารถตรวจจับและวัดความเข้มข้นของฝุ่นละอองขนาดเล็ก PM2.5 และ PM10 ได้ มีหน่วยวัดเป็นไมโครกรัมต่อลูกบาศก์เมตร (µg/m^3) มีความละเอียดในการวัดค่า 0.3 μg/m^3
โมดูล SDS011 ใช้แรงดันไฟเลี้ยง +5Vdc (4.7~5.3V) และรับส่งข้อมูลผ่าน Serial โดยใช้ขา TXD และ RXD (วงจรลอจิกทำงานที่ระดับแรงดันไฟฟ้า 3.3V) และตั้งค่า Baudrate ไว้เท่ากับ 9600 8N1
ผู้อ่านควรศึกษาคู่มือหรือเอกสาร Datasheet ของโมดูล SDS011 ก่อนนำอุปกรณ์ไปต่อทดลองใช้งาน เพื่อให้ใช้งานได้อย่างถูกต้องและไม่เกิดความเสียหาย
โดยปรกติ โมดูลเซ็นเซอร์จะส่งข้อมูลออกมา 10 ไบต์ ทุก ๆ 1 วินาที โดยอัตโนมัติ มีลำดับข้อมูลไบต์ดังนี้
ไบต์ที่ 0:
0xaa
ไบต์ที่ 1:
0xc0
ไบต์ที่ 2 และ 3: ค่า PM2.5 (low byte and high byte) นำไปหารด้วย 10
ไบต์ที่ 4 และ 5: ค่า PM10 (low byte and high byte) นำไปหารด้วย 10
ไบต์ที่ 6 และ 7: Reserved
ไบต์ที่ 7: Checksum
ไบต์ที่ 8:
0xab
สูตรการคำนวณค่า PM2.5 หรือ PM10 จากข้อมูล 2 ไบต์ในแต่ละกรณี
การเชื่อมต่อกับโมดูล SDS011 มีขาของคอนเนกเตอร์ดังนี้
Pin Name | Description |
NC | Not Connected |
1μm | PM2.5: 0-999μg/m3, PWM Output |
5V | 5V DC Input |
2.5μm | PM10: 0-999 μg/m3, PWM Output |
GND | Ground |
RXD | RXD (3.3V logic level) |
TXD | TXD (3.3V logic level) |
ให้ใช้แรงดันไฟเลี้ยง 5V USB สำหรับโมดูล SDS011 และเชื่อมต่อกับบอร์ดไมโครบิตดังนี้
SDS011 Pin | Microbit Pin |
GND | GND |
RXD | Pin0 (used as Tx pin) |
TXD | Pin1 (used as Rx pin) |
โค้ดตัวอย่างต่อไปนี้สาธิตการอ่านค่าจากโมดูล SDS011 แล้วนำมาแสดงผลบนจอ LCD 16x2 I2C (PCF8574)
การทำงานของโค้ดตัวอย่างนี้ จะต้องใช้ UART โดยเลือกใช้ขา pin0
และ pin1
ที่เชื่อมต่อและรับข้อมูลจากโมดูล SDS011 จากนั้นเมื่อรับข้อมูลไบต์ได้ครบ 10 ไบต์แล้ว และตรวจสอบข้อมูลที่ได้รับว่าถูกต้อง จึงแปลงข้อมูลไบต์ให้เป็นค่าตัวเลขสำหรับ PM2.5 และ PM10 แล้วนำไปแสดงบนบนหน้าจอ LCD 16x2 แบบ I2C (มีแอดเดรสของอุปกรณ์ตรงกับ 0x3f
) ถัดไปจึงมีการเปลี่ยนไปใช้ UART ที่เชื่อมต่อกับพอร์ต USB คอมพิวเตอร์ของผู้ใช้ เพื่อส่งข้อความไปยังหน้าต่าง REPL Terminal ของโปรแกรม Mu Editor ด้วยคำสั่ง print()
ถ้าต้องการจบการทำงานของโปรแกรม ให้กดปุ่ม Button A ค้างไว้
โค้ดตัวอย่างที่ 26: การอ่านค่าจากเซ็นเซอร์วัดอุณหภูมิแบบอินฟราเรด MLX90614
MLX90614 ของบริษัท Melexis เป็นเซ็นเซอร์วัดอุณหภูมิแบบไม่ต้องสัมผัส โดยใช้การตรวจจับรังสีอินฟราเรดจากวัตถุ (Non-Contact Infrared Temperature Sensor) แล้วนำมาคำนวณเพื่อให้ได้ค่าตัวเลขสำหรับอุณหภูมิ สื่อสารข้อมูลด้วยบัส I2C (ความเร็ว 100kHz และมีแอดเดรสตรงกับ 0x5a)
อุปกรณ์ที่ได้เลือกมาทดลองใช้งานคือ รุ่น MLX90614ESF-BAA TO-39 Package (โมดูล GY-906 / HW-691) สามารถวัดอุณหภูมิอากาศแวดล้อม (Ambient Temperature) ในช่วง -40 °C…+85 ˚C และอุณหภูมิของวัตถุ (Object Temperature) ในช่วง -70 °C…+380 ˚C มีความแม่นยำในการวัด +/- 0.5 ˚C และความละเอียด 0.02 °C (อ้างอิงจากเอกสาร Datasheet)
การอ่านข้อมูลสำหรับอุณหภูมิ จะต้องระบุแอดเดรสของรีจิสเตอร์ที่เก็บข้อมูลแต่ละตัวขนาด 16 บิตภายใน RAM ขนาด 32x16 เช่น
0x06
= TA (Ambient Temperature)0x07
= TOBJ1 (Object Temperature, Zone 1)
ข้อมูลที่อ่านได้ขนาด 2 ไบต์ จะต้องนำมาแปลงให้เป็น 16-bit signed แล้วคูณด้วย 0.02 และแปลงจากหน่วย Kelvin ให้เป็น Celsius ตามลำดับ
โค้ดสำหรับไฟล์ mlx90614.py ที่จำเป็นต้องใช้ร่วมกับโค้ดสาธิตการทำงาน มีดังนี้
จากการทำงานของโค้ดตัวอย่าง ข้อมูลที่ถูกส่งออกมาเป็นข้อความเอาต์พุต แสดงค่าตัวเลขสำหรับอุณหภูมิอากาศแวดล้อม และอุณหภูมิของวัตถุ เช่น สำหรับการทดลอง ได้นำแก้วที่ใส่กาแฟร้อน มาวางอยู่ห่างจากโมดูลเซ็นเซอร์ประมาณ 1 cm.
เราสามารถใช้โปรแกรม Mu Editor รับข้อความและแสดงรูปกราฟได้ง่าย เนื่อจากข้อความแต่ละบรรทัดที่ถูกส่งออกมา มีตัวเลข 2 ค่า ได้แก่ อุณหภูมิอากาศแวดล้อม และอุณหภูมิของวัตถุ ตามลำดับ เราจะมองเห็นกราฟ 2 เส้น ในหน้าต่าง Plotter ของ Mu Editor
เราพอจะมองเห็นการนำอุปกรณ์นี้ไปประยุกต์ใช้งาน เช่น การตรวจจับการเปลี่ยนแปลงอุณหภูมิของวัตถุ เปรียบเทียบกับอุณหภูมิอากาศแวดล้อม เป็นต้น
ข้อสังเกต: ปัจจัยอย่างเช่น ระยะห่างของวัตถุจากเซ็นเซอร์ สัมประสิทธิ์การแผ่รังสีความร้อน (Emissivity) ของวัตถุ มีผลต่อค่าของอุณหภูมิที่วัดได้
กล่าวสรุป
บอร์ดไมโครบิตสามารถนำมาใช้ เพื่อฝึกเขียนโค้ดด้วยภาษาไมโครไพธอนได้ และใช้ร่วมกับโมดูลหรือวงจรอิเล็กทรอนิกส์รูปแบบต่าง ๆ ได้ เหมาะสำหรับผู้เริ่มต้นเรียนรู้ภาษาไพธอนและใช้งานไมโครคอนโทรลเลอร์ในเบื้องต้น หรือมีบอร์ดไมโครบิตอยู่แล้ว
อย่างไรก็ตาม เนื่องด้วยข้อจำกัดของตัวประมวลผลหลัก (nRF51822) ของบอร์ดไมโครบิต (บอร์ดเวอร์ชันแรก v1.3 หรือ v1.5) อย่างเช่น ความเร็วในการประมวลผล (16MHz) ความจุของหน่วยความจำ Flash และ SRAM ที่ค่อนข้างน้อย อีกทั้งเฟิร์มแวร์ของไมโครไพธอนที่ใช้งานได้กับบอร์ดไมโครบิต (เป็นเวอร์ชัน MicroPython v1.9.2 Build 2017-09-01 / microbit v1.0.1) ดังนั้นการนำไปใช้งานที่มีความซับซ้อน อาจจะไม่เหมาะสม เมื่อเปรียบเทียบกับบอร์ดไมโครคอนโทรลเลอร์ที่เป็นตัวเลือกอื่น เช่น STM32 หรือ ESP32 เป็นต้น
เผยแพร่ภายใต้ลิขสิทธิ์ Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)
Last updated