3.1. ไมโครคอนโทรลเลอร์¶
OpenMV Cam ทำงานบน ไมโครคอนโทรลเลอร์ (MCU): ชิปตัวเดียวที่รวม CPU, หน่วยความจำใช้งาน (RAM), พื้นที่จัดเก็บโปรแกรม (แฟลช) และชุด อุปกรณ์ต่อพ่วง -- บล็อกฮาร์ดแวร์สำหรับโต้ตอบกับโลกภายนอก
อุปกรณ์ต่อพ่วงคือส่วนที่น่าสนใจ แต่ละตัวเป็นชิ้นส่วนซิลิคอนที่ทำหน้าที่เฉพาะอย่างหนึ่ง: ขับพินให้สูงหรือต่ำ, วัดแรงดันไฟฟ้าแบบอนาล็อก, ส่งไบต์ผ่านบัสอนุกรม CPU กำหนดค่าและอ่านข้อมูลจากอุปกรณ์ต่อพ่วงแต่ละตัวผ่าน รีจิสเตอร์ -- ที่อยู่หน่วยความจำคงที่ที่ฮาร์ดแวร์คอยตรวจสอบและอัปเดต
MicroPython ห่อหุ้มรีจิสเตอร์เหล่านั้นเป็นคลาสใน machine machine.Pin(...) คืนออบเจ็กต์ที่ควบคุม general-purpose input/output (GPIO) พิน -- สายที่ชิปสามารถดึงให้ สูง (ประมาณ 3.3 V) หรือ ต่ำ (ประมาณ 0 V) หรืออ่านเป็นหนึ่งในสองสถานะนั้นเมื่อมีสิ่งภายนอกขับมัน machine.ADC(...) เปิดใช้งานตัวแปลงอนาล็อกเป็นดิจิทัล ซึ่งวัดแรงดันบนพินและรายงานเป็นตัวเลข machine.UART(...) เรียกใช้งาน universal asynchronous receiver/transmitter (UART) -- อุปกรณ์ต่อพ่วงที่ส่งและรับไบต์ทีละบิตผ่านคู่สาย TX (ส่ง) และ RX (รับ) คลาสอื่นๆ ครอบคลุมอุปกรณ์ต่อพ่วงที่เหลือ สคริปต์อ่านและเขียนออบเจ็กต์ Python และ MicroPython แปลงการเข้าถึงแต่ละครั้งเป็นการอ่านและเขียนรีจิสเตอร์ที่สอดคล้องกัน ซึ่งเคลื่อนย้ายบิตบนสายไฟฟ้าจริง
MCU บรรจุ CPU, หน่วยความจำ และอุปกรณ์ต่อพ่วงไว้ในชิปเดียว อุปกรณ์ต่อพ่วงแต่ละตัวเปิดเผยต่อ Python ผ่านคลาสใน machine¶
3.1.1. ลูปหลัก¶
โปรแกรมไมโครคอนโทรลเลอร์เกือบทุกตัวมีรูปแบบเดียวกัน: การตั้งค่าครั้งเดียวที่ต้นสคริปต์ (นำเข้าโมดูล, กำหนดค่าพิน, เปิดบัส) จากนั้นตามด้วยลูป while True: แบบอนันต์ที่ท้าย ภายในลูป โปรแกรมอ่านอินพุต ตัดสินใจ และอัปเดตเอาต์พุตซ้ำแล้วซ้ำเล่า ลูป คือ โปรแกรม เมื่อสคริปต์ออก อุปกรณ์จะหยุดทำงาน
# setup, runs once
from machine import Pin
led = Pin("P0", Pin.OUT)
# main loop, runs forever
while True:
led.value(1)
# ... do work ...
led.value(0)
# ... do other work ...
รูปแบบนี้ -- ตั้งค่าครั้งเดียว จากนั้นวนซ้ำตลอด -- คือรูปแบบ main loop ทุกสิ่งที่ตามมาเกี่ยวข้องกับสิ่งที่อยู่ภายในมัน
3.1.2. การควบคุมแบบเรียลไทม์¶
โปรแกรมเดสก์ท็อปทำงานร่วมกับโปรแกรมอื่นๆ มากมาย ระบบปฏิบัติการจัดตารางงานข้าม เธรด หนึ่งหรือหลายตัว -- กระแสการทำงานอิสระที่สลับระหว่างกันทุกมิลลิวินาที เมื่อเธรดหนึ่งรอ I/O (ดิสก์, เครือข่าย, ผู้ใช้เลื่อนเมาส์) ระบบปฏิบัติการจะส่ง CPU ให้กับเธรดอื่น โปรแกรมส่วนใหญ่ขับเคลื่อนด้วยเหตุการณ์: window manager เรียกโค้ดของคุณเมื่ออินพุตมาถึง ไลบรารี HTTP กลับมาที่โค้ดของคุณเมื่อไบต์มาถึงบนซ็อกเก็ต สิ่งที่ใหญ่กว่าเป็นผู้เรียกคุณ
โปรแกรมไมโครคอนโทรลเลอร์เป็นตรงกันข้าม โดยค่าเริ่มต้นไม่มีระบบปฏิบัติการ ไม่มีตัวกำหนดตาราง และไม่มีเธรดอื่น ลูปหลักที่แสดงไว้คือ ลูปเดียว อุปกรณ์ต่อพ่วงส่งอินเทอร์รัปต์หรือเปิดเผยแฟล็กสถานะ ลูปจะ poll หรือจัดการอินเทอร์รัปต์โดยตรง หากลูปหยุดใน time.sleep_ms(1000) อุปกรณ์จะไม่ทำอะไรในช่วงวินาทีนั้น ไม่มีเธรดอื่นมาเติมช่องว่าง
ผลลัพธ์สองประการที่เกิดขึ้นและใช้ได้ทุกที่:
เวลาเป็นจริง การอ่านพินสองครั้งในลูปที่แน่นต้องใช้ไมโครวินาที การหลับเป็นสิบมิลลิวินาทีหมายความว่าสิบมิลลิวินาทีที่ไม่มีอะไรเกิดขึ้น รูปแบบ การจับเวลาแบบไม่บล็อก คือการตอบสนอง
ฮาร์ดแวร์เป็นจริง การตั้งค่า
machine.Pin.valueเป็น1จะใส่แรงดันประมาณ 3.3 V บนสายไฟจริง การตั้งเป็น0จะใส่ประมาณ 0 V ชิ้นส่วนอื่นของวงจรเห็นแรงดันนั้นทันที -- รวมถึงส่วนประกอบที่พินอาจทำให้เสียหายหากขับผิด