3.10. GPIO input¶
การอ่านสวิตช์ (หรือสัญญาณดิจิทัลใดก็ตาม) จากพิน GPIO ผ่าน machine.Pin อีกครั้ง คราวนี้กำหนดค่าเป็น input อินเทอร์เฟซนี้สมมาตรกับ output: กำหนดค่าโหมด จากนั้นสำรวจค่าพินในลูปหลัก หรือลงทะเบียนตัวจัดการอินเทอร์รัปต์ที่จะทำงานเมื่อค่าเปลี่ยนแปลง
3.10.1. การกำหนดค่า input¶
ส่ง Pin.IN ไปยัง constructor และเปิดใช้งานตัวต้านทานดึงตามต้องการ:
from machine import Pin
button = Pin("P0", Pin.IN, Pin.PULL_UP)
นั่นจะกำหนดค่า P0 เป็น input พร้อมตัวต้านทานดึงขึ้นภายในของ MCU ที่เปิดใช้งาน เมื่อไม่มีอะไรเชื่อมต่อกับพิน ตัวดึงขึ้นจะถือพินไว้ที่สูง; การปิดสวิตช์จากพินไปยังกราวด์จะดึงพินลงต่ำ
3.10.2. การอ่านค่า¶
value() ที่ไม่มีอาร์กิวเมนต์จะส่งคืนสถานะปัจจุบัน -- 0 สำหรับต่ำ, 1 สำหรับสูง:
if button.value() == 0:
print("button pressed")
else:
print("button released")
ในรูปแบบลูปหลัก การสำรวจจะมีลักษณะดังนี้:
while True:
if button.value() == 0:
do_action()
time.sleep_ms(50)
การหยุดพัก 50 ms ป้องกันไม่ให้ลูปทำงานด้วยความเร็ว CPU เต็มที่
3.10.3. การ input ที่ขับเคลื่อนด้วยอินเทอร์รัปต์¶
การสำรวจใช้ได้ผล แต่ทุกรอบของลูปหลักใช้เวลา CPU เมื่อ input เปลี่ยนแปลงไม่บ่อย -- การกดปุ่มหนึ่งครั้งต่อนาที สัญญาณเตือน -- irq() ลงทะเบียนตัวจัดการที่ทำงาน เฉพาะเมื่อ พินเปลี่ยนแปลง
ตัวจัดการทำงานใน interrupt context ซึ่งจำกัดสิ่งที่มันสามารถทำได้:
ไม่มีการจัดสรรหน่วยความจำ. การสร้างออบเจ็กต์ใหม่ -- รายการ สตริง ข้อยกเว้น สตริงที่จัดรูปแบบ -- อาจล้มเหลวภายใน ISR เพราะฮีปถูกล็อค จัดสรรบัฟเฟอร์ที่ตัวจัดการต้องการไว้ล่วงหน้าที่ module scope
ไม่มีงานที่ใช้เวลานาน. ตัวจัดการควรส่งงานต่อและส่งคืน การใช้เวลาจริงๆ ภายใน ISR จะทำให้ทุกอย่างล่าช้า (อินเทอร์รัปต์อื่นๆ ลูปหลัก การรับส่ง USB)
ไม่มีการพิมพ์ใน ISR ที่แน่น.
print()จัดสรรหน่วยความจำ บล็อกบน UART และเป็นหนึ่งในสิ่งที่แพงที่สุดที่ตัวจัดการสามารถทำได้
รูปแบบมาตรฐานคือให้ ISR จัดตาราง งานจริงผ่าน micropython.schedule() ซึ่งจัดคิวฟังก์ชันให้ทำงานกลับใน main context ที่จุดปลอดภัยถัดไป:
import micropython
def handle_press(pin):
print("button pressed")
def on_press(pin):
micropython.schedule(handle_press, pin)
button.irq(handler=on_press, trigger=Pin.IRQ_FALLING)
ISR มีหนึ่งบรรทัด: จัดคิวคอลแบ็กและส่งคืน จากนั้น handle_press จะทำงานใน normal context ซึ่งการจัดสรรหน่วยความจำ print() และ I/O ที่ช้าทั้งหมดปลอดภัยอีกครั้ง
อาร์กิวเมนต์ trigger เลือกว่าขอบสัญญาณใดจะยิง:
Pin.IRQ_FALLING-- 1 ไปยัง 0Pin.IRQ_RISING-- 0 ไปยัง 1Pin.IRQ_FALLING|Pin.IRQ_RISING-- ทั้งสองขอบ