Python thường gắn với máy chủ và máy tính cá nhân. Nhưng nó cũng chạy được trên vi điều khiển — những con chip chỉ có vài trăm kilobyte bộ nhớ.
MicroPython
MicroPython là bản cài đặt lại Python 3 cho vi điều khiển. Nó không phải Python đầy đủ — thư viện chuẩn bị cắt gọn nhiều — nhưng cú pháp và các khái niệm cốt lõi giữ nguyên.
from machine import Pin
import time
den = Pin(2, Pin.OUT)
while True:
den.value(1)
time.sleep(0.5)
den.value(0)
time.sleep(0.5)
So với việc viết C cho vi điều khiển, khác biệt về công sức là rất lớn — nhất là với người đã quen Python.
Phần cứng phổ biến
ESP32 là lựa chọn được dùng nhiều nhất. Nó có sẵn WiFi và Bluetooth, giá rẻ, và cộng đồng lớn nên dễ tìm tài liệu.
Raspberry Pi Pico cũng phổ biến, đặc biệt bản có WiFi. Nó chạy được cả MicroPython lẫn CircuitPython.
Cần phân biệt với Raspberry Pi thông thường — đó là máy tính chạy Linux đầy đủ, cài Python bình thường được, không cần MicroPython.
Bắt đầu thế nào?
Quy trình chung: nạp firmware MicroPython vào bo mạch, rồi dùng công cụ để đẩy code lên.
pip install esptool mpremote
# Nạp firmware (một lần)
esptool.py --port /dev/ttyUSB0 erase_flash
esptool.py --port /dev/ttyUSB0 write_flash 0x1000 esp32-firmware.bin
# Làm việc với bo mạch
mpremote connect /dev/ttyUSB0 repl # dấu nhắc tương tác
mpremote connect /dev/ttyUSB0 fs cp main.py :main.py
mpremote connect /dev/ttyUSB0 run test.py
Điểm hay là có dấu nhắc tương tác chạy ngay trên vi điều khiển — bạn gõ lệnh và thấy đèn sáng tắt ngay lập tức. Với người học điện tử, vòng lặp phản hồi này quý hơn nhiều so với chu trình biên dịch và nạp lại.
Đọc cảm biến
from machine import Pin, ADC, I2C
import time
# Cảm biến tương tự
cam_bien = ADC(Pin(34))
cam_bien.atten(ADC.ATTN_11DB)
# Giao tiếp I2C
i2c = I2C(0, scl=Pin(22), sda=Pin(21))
print(i2c.scan()) # tìm thiết bị đang nối
while True:
gia_tri = cam_bien.read()
print(f"Giá trị: {gia_tri}")
time.sleep(1)
Kết nối mạng
import network, urequests, ujson, time
def ket_noi_wifi(ten, mat_khau, cho_toi_da=20):
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
if not wlan.isconnected():
wlan.connect(ten, mat_khau)
bat_dau = time.time()
while not wlan.isconnected():
if time.time() - bat_dau > cho_toi_da:
raise OSError("Không kết nối được WiFi")
time.sleep(0.5)
return wlan.ifconfig()
print(ket_noi_wifi("TenWifi", "MatKhau"))
# Gửi dữ liệu lên máy chủ
r = urequests.post(
"https://api.example.com/du-lieu",
json={"nhiet_do": 28.5, "do_am": 65},
)
r.close() # BẮT BUỘC - không đóng sẽ cạn bộ nhớ
Việc đóng phản hồi rất quan trọng. Trên máy tính bạn có thể lơ là, nhưng với vài trăm kilobyte RAM thì bỏ sót vài lần là chương trình dừng vì hết bộ nhớ.
Những khác biệt cần lưu ý
Bộ nhớ rất hạn chế. Vài chục tới vài trăm kilobyte. Không có chuyện nạp cả tệp lớn vào bộ nhớ.
import gc
gc.collect()
print(gc.mem_free()) # xem còn bao nhiêu byte
Thư viện chuẩn bị cắt gọn. Nhiều module có phiên bản rút gọn với tên bắt đầu bằng u: ujson, urequests, utime.
Số thực có thể bị hạn chế. Một số bo mạch chỉ hỗ trợ độ chính xác đơn.
Không có nhiều tiến trình. Có luồng ở mức hạn chế, nhưng mô hình thường dùng là vòng lặp sự kiện hoặc ngắt.
Xử lý ngắt
from machine import Pin
dem = 0
def khi_nhan(pin):
global dem
dem += 1 # giữ hàm ngắt càng ngắn càng tốt
nut = Pin(0, Pin.IN, Pin.PULL_UP)
nut.irq(trigger=Pin.IRQ_FALLING, handler=khi_nhan)
Trong hàm xử lý ngắt, tránh cấp phát bộ nhớ và tránh in ấn. Hãy chỉ đặt một cờ rồi xử lý trong vòng lặp chính.
Tiết kiệm điện
import machine
# Ngủ sâu, thức dậy sau 60 giây
machine.deepsleep(60_000)
Với thiết bị chạy pin, chế độ ngủ sâu là yếu tố quyết định. Một thiết bị đo nhiệt độ mỗi giờ có thể chạy hàng tháng bằng pin nếu ngủ đúng cách, hoặc hết pin trong vài ngày nếu không.
CircuitPython
Đây là nhánh phát triển từ MicroPython, tập trung vào người mới học. Bo mạch hiện ra như ổ đĩa USB — bạn chép tệp code.py vào là nó chạy, không cần công cụ gì.
Đơn giản hơn cho người bắt đầu, nhưng MicroPython thường được ưa chuộng hơn cho dự án nghiêm túc vì hỗ trợ nhiều phần cứng hơn.
Khi nào dùng Python trên vi điều khiển?
Hợp lý: làm mẫu nhanh, dự án cá nhân, dạy học, thiết bị đo đơn giản, sản phẩm số lượng nhỏ.
Chưa hợp lý: điều khiển thời gian thực chặt chẽ, sản phẩm số lượng lớn cần tối ưu chi phí linh kiện, hoặc yêu cầu tiết kiệm điện tới mức cực hạn.
Với những trường hợp sau, C vẫn là lựa chọn. Nhưng nhiều dự án bắt đầu bằng MicroPython để kiểm chứng ý tưởng rồi mới viết lại — cách làm hợp lý vì bạn xác nhận được thiết kế trước khi đầu tư công sức.