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 เลือกว่าขอบสัญญาณใดจะยิง: