Phương pháp thực hiện độ trễ / đo thời gian ở cấp độ microgiây (μs) bằng Python
Lời mở đầu
Gần đây, tôi đang học về GPIO của Raspberry Pi và muốn dùng Python để đọc dữ liệu từ cảm biến nhiệt độ và độ ẩm DHT11. DHT11 sử dụng giao thức một dây (single bus), đòi hỏi độ trễ ở cấp độ microgiây. Hàm sleep() dường như không thể đáp ứng yêu cầu này. Sau đó, tôi phát hiện ra rằng dấu thời gian (timestamp) có thể chính xác đến 7 chữ số sau dấu phẩy, tức là 0,1 microgiây. Dù thực tế có thể không đạt được độ chính xác này, nhưng nó vẫn đủ dùng.
Phương pháp này chỉ áp dụng được trên hệ thống Linux. Trên Windows, không rõ lý do gì, mọi nỗ lực tạo độ trễ đều cho kết quả tối thiểu 1000 microgiây.
1 giây (s) = 1000 miligiây (ms) = 1.000.000 microgiây (μs)
Dấu thời gian là gì?
Dấu thời gian là tổng số giây kể từ thời điểm 00:00:00 ngày 01 tháng 01 năm 1970 theo giờ Greenwich (tương đương 08:00:00 ngày 01 tháng 01 năm 1970 theo giờ Bắc Kinh) đến hiện tại.
Phương pháp thực hiện
Ghi lại dấu thời gian ban đầu, sau đó vào vòng lặp, mỗi lần lặp ghi lại một dấu thời gian. Điều kiện lặp là: dấu thời gian hiện tại trừ đi dấu thời gian ban đầu nhỏ hơn thời gian đặt trước thì tiếp tục lặp, cho đến khi lớn hơn hoặc bằng thời gian đặt trước.
Mã nguồn:
import time # Nhập module time
# https://blog.zeruns.com/
def delayMicrosecond(t): # Hàm trễ cấp microgiây
start, end = 0, 0 # Khai báo biến
start = time.time() # Ghi lại thời gian bắt đầu
t = (t - 3) / 1000000 # Chuyển đổi đơn vị t thành giây, -3 là bù thời gian
while end - start < t: # Lặp đến khi chênh lệch thời gian lớn hơn hoặc bằng giá trị đặt
end = time.time() # Ghi lại thời gian kết thúc
Cách sử dụng: Sao chép đoạn mã trên vào chương trình của bạn, sau đó gọi hàm delayMicrosecond(t), trong đó t là thời gian trễ, đơn vị là microgiây.
Trong mã nguồn trên, t - 3 là bù thời gian, vì việc gọi hàm và thực thi vòng lặp cũng tiêu tốn thời gian. Bạn có thể tự điều chỉnh giá trị này dựa trên kết quả kiểm thử. Tôi thử nghiệm trên Raspberry Pi 4 và thấy có thêm 3 microgiây tiêu tốn, nên tôi trừ đi 3.
Ví dụ
import time # Nhập module time
# https://blog.zeruns.com/
def delayMicrosecond(t): # Hàm trễ cấp microgiây
start, end = 0, 0 # Khai báo biến
start = time.time() # Ghi lại thời gian bắt đầu
t = (t - 3) / 1000000 # Chuyển đổi đơn vị t thành giây, -3 là bù thời gian
while end - start < t: # Lặp đến khi chênh lệch thời gian lớn hơn hoặc bằng giá trị đặt
end = time.time() # Ghi lại thời gian kết thúc
a = time.time() # Ghi lại thời gian bắt đầu thực thi hàm trễ
delayMicrosecond(35) # Trễ 35 microgiây
b = time.time() # Ghi lại thời gian kết thúc hàm trễ
print("https://blog.zeruns.com/")
print((b - a) * 1000000) # In ra thời gian thực thi hàm trễ
Kết quả:
Gợi ý đọc thêm
- Khuyến nghị VPS/máy chủ đám mây giá rẻ và hiệu quả: https://blog.zeruns.com/archives/383.html
- Các bài viết về Python: https://blog.zeruns.com/category/Python/
- Đọc dữ liệu nhiệt độ và độ ẩm từ DHT11, DHT22, SHTC3 bằng Arduino: https://blog.zeruns.com/archives/527.html
- Danh sách ưu đãi dành riêng cho học sinh: https://blog.zeruns.com/archives/557.html
- Cách xây dựng blog cá nhân: https://blog.zeruns.com/archives/218.html


