time --- các hàm liên quan đến thời gian¶
Mô-đun time cung cấp các hàm để lấy thời gian và ngày tháng hiện tại, đo khoảng thời gian và tạo độ trễ.
Epoch Thời gian: Các OpenMV Cams dựa trên Alif và i.MX RT sử dụng epoch POSIX là 1970-01-01 00:00:00 UTC. Các OpenMV Cams dựa trên STM32 sử dụng epoch là 2000-01-01 00:00:00 UTC. Năm epoch có thể xác định tại thời điểm chạy với gmtime(0)[0].
Duy trì ngày/giờ lịch thực tế: Điều này yêu cầu Real Time Clock (RTC). Trên OpenMV Cam, thời gian hệ thống được cung cấp bởi đối tượng machine.RTC. Thời gian lịch hiện tại có thể được thiết lập với machine.RTC().datetime(tuple) và được duy trì bởi một trong các cách sau:
Pin dự phòng (thành phần tùy chọn trên một số OpenMV Cams).
Giao thức thời gian qua mạng như
ntptime(yêu cầu kết nối mạng).Cài đặt thủ công mỗi lần khởi động. RTC thường được duy trì qua các lần soft reset, nhưng sẽ mất khi mất nguồn điện trừ khi có pin dự phòng.
Nếu thời gian lịch không được duy trì, các hàm dưới đây tham chiếu đến thời gian tuyệt đối hiện tại sẽ không hoạt động như mong đợi.
Hàm¶
- time.gmtime(secs: int | None = None) Tuple[int, int, int, int, int, int, int, int]¶
- time.localtime(secs: int | None = None) Tuple[int, int, int, int, int, int, int, int]¶
Chuyển đổi thời gian secs được biểu thị bằng giây kể từ Epoch (xem ở trên) thành một tuple 8 phần tử chứa:
(year, month, mday, hour, minute, second, weekday, yearday)Nếu secs không được cung cấp hoặc là None, thì thời gian hiện tại từ RTC sẽ được sử dụng.Hàm
gmtime()trả về tuple ngày-giờ theo UTC, vàlocaltime()trả về tuple ngày-giờ theo giờ địa phương.Định dạng của các mục trong tuple 8 phần tử là:
year bao gồm thế kỷ (ví dụ: 2014).
month là 1-12
mday là 1-31
hour là 0-23
minute là 0-59
second là 0-59
weekday là 0-6 cho Thứ Hai-Chủ Nhật
yearday là 1-366
- time.mktime(date_time_tuple: Tuple[int, int, int, int, int, int, int, int]) int¶
Đây là hàm nghịch đảo của localtime. Đối số của nó là một tuple đầy đủ 8 phần tử biểu thị thời gian theo localtime. Nó trả về một số nguyên là số giây kể từ epoch thời gian.
- time.sleep(seconds: float) None¶
Ngủ trong số giây đã cho. seconds có thể là số thực dấu phẩy động để ngủ trong một phần giây. Để có độ trễ chi tiết hơn hoặc chỉ số nguyên, hãy dùng các hàm
sleep_ms()vàsleep_us().Gọi
sleep(), bao gồmsleep(0)được đảm bảo sẽ gọi các hàm callback đang chờ xử lý.
- time.sleep_ms(ms: int) None¶
Trễ trong số millisecond đã cho, nên là dương hoặc 0.
Hàm này sẽ trễ ít nhất số millisecond đã cho, nhưng có thể mất lâu hơn nếu có các xử lý khác cần thực hiện, ví dụ như các interrupt handler hoặc các luồng khác. Truyền vào 0 cho ms vẫn cho phép các xử lý khác này xảy ra. Dùng
sleep_us()để có độ trễ chính xác hơn.Gọi
sleep_ms(), bao gồmsleep_ms(0)được đảm bảo sẽ gọi các hàm callback đang chờ xử lý.
- time.sleep_us(us: int) None¶
Trễ trong số microsecond đã cho, nên là dương hoặc 0.
Hàm này cố gắng cung cấp độ trễ chính xác ít nhất us microsecond, nhưng có thể mất lâu hơn nếu hệ thống có các xử lý ưu tiên cao hơn cần thực hiện.
- time.ticks_ms() int¶
Trả về bộ đếm millisecond tăng dần với điểm tham chiếu tùy ý, cuộn vòng sau một giá trị nào đó.
Giá trị cuộn vòng không được hiển thị rõ ràng, nhưng chúng ta sẽ gọi nó là TICKS_MAX để đơn giản hóa việc thảo luận. Chu kỳ của các giá trị là TICKS_PERIOD = TICKS_MAX + 1. TICKS_PERIOD được đảm bảo là lũy thừa của hai, nhưng có thể khác nhau giữa các port. Giá trị chu kỳ giống nhau được sử dụng cho tất cả các hàm
ticks_ms(),ticks_us(),ticks_cpu()(để đơn giản). Vì vậy, các hàm này sẽ trả về giá trị trong khoảng [0 .. TICKS_MAX], toàn phần, tổng cộng TICKS_PERIOD giá trị. Lưu ý rằng chỉ các giá trị không âm được sử dụng. Trong hầu hết các trường hợp, bạn nên coi các giá trị được trả về bởi các hàm này là không trong suốt. Các thao tác duy nhất có thể thực hiện là các hàmticks_diff()vàticks_add()được mô tả bên dưới.Lưu ý: Thực hiện các phép toán toán học tiêu chuẩn (+, -) hoặc các toán tử quan hệ (<, <=, >, >=) trực tiếp trên các giá trị này sẽ dẫn đến kết quả không hợp lệ. Thực hiện các phép toán toán học và sau đó truyền kết quả làm đối số cho
ticks_diff()hoặcticks_add()cũng sẽ dẫn đến kết quả không hợp lệ từ các hàm sau.
- time.ticks_us() int¶
Tương tự như
ticks_ms()ở trên, nhưng tính bằng microsecond.
- time.ticks_cpu() int¶
Tương tự như
ticks_ms()vàticks_us(), nhưng với độ phân giải cao nhất có thể trong hệ thống. Thường đây là clock của CPU, và đó là lý do hàm được đặt tên như vậy. Nhưng không nhất thiết phải là clock CPU, một nguồn thời gian khác có sẵn trong hệ thống (ví dụ: bộ định thời độ phân giải cao) có thể được sử dụng thay thế. Đơn vị thời gian chính xác (độ phân giải) của hàm này không được chỉ định ở cấp mô-đuntime, nhưng tài liệu cho một port cụ thể có thể cung cấp thêm thông tin chi tiết hơn. Hàm này được dùng cho việc đo hiệu suất rất chi tiết hoặc các vòng lặp thời gian thực rất chặt chẽ. Tránh dùng nó trong mã portable. Nó khả dụng trên tất cả các OpenMV Cams.
- time.ticks_add(ticks: int, delta: int) int¶
Dịch chuyển giá trị ticks theo một số đã cho, có thể là dương hoặc âm. Cho một giá trị ticks, hàm này cho phép tính giá trị ticks delta ticks trước hoặc sau nó, theo định nghĩa số học modular của các giá trị tick (xem
ticks_ms()ở trên). Tham số ticks phải là kết quả trực tiếp của lời gọi đến các hàmticks_ms(),ticks_us(), hoặcticks_cpu()(hoặc từ lời gọi trước đó đếnticks_add()). Tuy nhiên, delta có thể là bất kỳ số nguyên hoặc biểu thức số nào.ticks_add()hữu ích để tính thời hạn cho các sự kiện/tác vụ. (Lưu ý: bạn phải dùng hàmticks_diff()để làm việc với thời hạn.)Ví dụ:
# Find out what ticks value there was 100ms ago print(ticks_add(time.ticks_ms(), -100)) # Calculate deadline for operation and test for it deadline = ticks_add(time.ticks_ms(), 200) while ticks_diff(deadline, time.ticks_ms()) > 0: do_a_little_of_something() # Find out TICKS_MAX used by this port print(ticks_add(0, -1))
- time.ticks_diff(ticks1: int, ticks2: int) int¶
Đo sự khác biệt ticks giữa các giá trị trả về từ các hàm
ticks_ms(),ticks_us(), hoặcticks_cpu(), dưới dạng giá trị có dấu có thể cuộn vòng.Thứ tự đối số giống như toán tử trừ,
ticks_diff(ticks1, ticks2)có cùng nghĩa vớiticks1 - ticks2. Tuy nhiên, các giá trị được trả về bởiticks_ms(), v.v. có thể cuộn vòng, vì vậy việc sử dụng phép trừ trực tiếp trên chúng sẽ tạo ra kết quả không đúng. Đó là lý doticks_diff()cần thiết, nó thực hiện số học modular (hay cụ thể hơn là số học vòng) để tạo ra kết quả đúng ngay cả với các giá trị cuộn vòng (miễn là chúng không quá xa nhau, xem bên dưới). Hàm trả về giá trị có dấu trong khoảng [-TICKS_PERIOD/2 .. TICKS_PERIOD/2-1] (đó là định nghĩa khoảng điển hình cho số nguyên nhị phân có dấu theo two's-complement). Nếu kết quả âm, nghĩa là ticks1 xảy ra trước ticks2 theo thời gian. Ngược lại, nghĩa là ticks1 xảy ra sau ticks2. Điều này chỉ đúng khi ticks1 và ticks2 cách nhau không quá TICKS_PERIOD/2-1 ticks. Nếu điều đó không thỏa mãn, kết quả không đúng sẽ được trả về. Cụ thể, nếu hai giá trị tick cách nhau TICKS_PERIOD/2-1 ticks, giá trị đó sẽ được hàm trả về. Tuy nhiên, nếu TICKS_PERIOD/2 ticks thực tế đã qua giữa chúng, hàm sẽ trả về -TICKS_PERIOD/2 thay thế, tức là giá trị kết quả sẽ cuộn vòng sang khoảng âm của các giá trị có thể.Lý do không chính thức của các ràng buộc trên: Giả sử bạn bị nhốt trong một phòng không có phương tiện nào để theo dõi thời gian trôi qua ngoài một chiếc đồng hồ 12 vạch tiêu chuẩn. Nếu bạn nhìn vào mặt đồng hồ bây giờ, và không nhìn lại trong 13 giờ nữa (ví dụ: nếu bạn ngủ lâu), thì khi bạn cuối cùng nhìn lại, có vẻ như chỉ có 1 giờ trôi qua. Để tránh nhầm lẫn này, hãy nhìn đồng hồ thường xuyên. Ứng dụng của bạn cũng nên làm như vậy. Phép ẩn dụ "ngủ quá lâu" cũng ánh xạ trực tiếp vào hành vi ứng dụng: đừng để ứng dụng của bạn chạy bất kỳ tác vụ đơn lẻ nào quá lâu. Chạy các tác vụ theo từng bước và theo dõi thời gian ở giữa.
ticks_diff()được thiết kế để đáp ứng các mẫu sử dụng đa dạng, bao gồm:Polling với timeout. Trong trường hợp này, thứ tự các sự kiện được biết trước, và bạn chỉ xử lý kết quả dương của
ticks_diff()# Wait for GPIO pin to be asserted, but at most 500us start = time.ticks_us() while pin.value() == 0: if time.ticks_diff(time.ticks_us(), start) > 500: raise TimeoutError
Lập lịch sự kiện. Trong trường hợp này, kết quả
ticks_diff()có thể âm nếu một sự kiện bị trễ:# This code snippet is not optimized now = time.ticks_ms() scheduled_time = task.scheduled_time() if ticks_diff(scheduled_time, now) > 0: print("Too early, let's nap") sleep_ms(ticks_diff(scheduled_time, now)) task.run() elif ticks_diff(scheduled_time, now) == 0: print("Right at time!") task.run() elif ticks_diff(scheduled_time, now) < 0: print("Oops, running late, tell task to run faster!") task.run(run_faster=true)
Lưu ý: Đừng truyền các giá trị
time()choticks_diff(), bạn nên sử dụng các phép toán toán học thông thường trên chúng. Nhưng lưu ý rằngtime()có thể (và sẽ) cũng tràn số. Điều này được biết đến là https://en.wikipedia.org/wiki/Year_2038_problem .
- time.time() int¶
Trả về số giây, dưới dạng số nguyên, kể từ Epoch, giả sử rằng RTC cơ bản được cài đặt và duy trì như mô tả ở trên. Nếu RTC không được cài đặt, hàm này trả về số giây kể từ điểm tham chiếu thời gian đặc thù của port (đối với các board nhúng không có RTC có pin dự phòng, thường là kể từ khi khởi động hoặc reset). Nếu bạn muốn phát triển ứng dụng MicroPython portable, bạn không nên dựa vào hàm này để cung cấp độ chính xác cao hơn giây. Nếu bạn cần độ chính xác cao hơn, timestamp tuyệt đối, hãy dùng
time_ns(). Nếu thời gian tương đối chấp nhận được thì dùng các hàmticks_ms()vàticks_us(). Nếu bạn cần thời gian lịch,gmtime()hoặclocaltime()không có đối số là lựa chọn tốt hơn.Khác biệt so với CPython
Trong CPython, hàm này trả về số giây kể từ Unix epoch (1970-01-01 00:00 UTC) dưới dạng giá trị dấu phẩy động, thường với độ chính xác microsecond. Trên OpenMV Cam, nó trả về một số nguyên với độ chính xác một giây -- phần cứng không thể biểu diễn cả khoảng thời gian dài lẫn độ chính xác dưới giây trong kiểu float -- và epoch khác nhau theo board (xem Epoch Thời gian ở trên). Nếu không có RTC có pin dự phòng đã được cài đặt, nó thay vào đó đếm giây kể từ khi khởi động/reset.
Hàm khởi tạo¶
- class time.clock¶
Trả về một đối tượng clock.
Phương thức¶
- fps() float¶
Dừng theo dõi thời gian đã trôi qua và trả về FPS (số khung hình trên giây) hiện tại.
Luôn gọi
ticktrước khi gọi hàm này.