time — funções relacionadas a tempo

O módulo time fornece funções para obter a data e hora atuais, medir intervalos de tempo e criar atrasos.

Época de tempo: As OpenMV Cams baseadas em Alif e i.MX RT usam a época POSIX de 1970-01-01 00:00:00 UTC. As OpenMV Cams baseadas em STM32 usam uma época de 2000-01-01 00:00:00 UTC. O ano da época pode ser determinado em tempo de execução com gmtime(0)[0].

Manutenção da data/hora real do calendário: Isso requer um Relógio de Tempo Real (RTC). Na OpenMV Cam, o tempo do sistema é fornecido pelo objeto machine.RTC. A hora atual do calendário pode ser definida com machine.RTC().datetime(tuple) e é mantida por um dos seguintes meios:

  • Uma bateria de backup (um componente opcional em algumas OpenMV Cams).

  • Um protocolo de tempo em rede como o ntptime (requer uma conexão de rede).

  • Defini-la manualmente a cada inicialização. O RTC então é tipicamente mantido durante soft resets, mas é perdido em caso de perda de energia, a menos que uma bateria de backup esteja instalada.

Se a hora do calendário não for mantida, as funções abaixo que referenciam a hora absoluta atual não se comportarão como esperado.

Funções

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]

Converte o tempo secs expresso em segundos desde a Época (veja acima) em uma tupla de 8 elementos que contém: (year, month, mday, hour, minute, second, weekday, yearday) Se secs não for fornecido ou for None, então a hora atual do RTC é usada.

A função gmtime() retorna uma tupla de data-hora em UTC, e localtime() retorna uma tupla de data-hora em hora local.

O formato das entradas na tupla de 8 elementos é:

  • year inclui o século (por exemplo 2014).

  • month vai de 1-12

  • mday vai de 1-31

  • hour vai de 0-23

  • minute vai de 0-59

  • second vai de 0-59

  • weekday vai de 0-6 para Seg-Dom

  • yearday vai de 1-366

time.mktime(date_time_tuple: Tuple[int, int, int, int, int, int, int, int]) int

Esta é a função inversa de localtime. Seu argumento é uma tupla completa de 8 elementos que expressa um tempo conforme localtime. Ela retorna um inteiro que é o número de segundos desde a época de tempo.

time.sleep(seconds: float) None

Aguarda pelo número de segundos fornecido. seconds pode ser um número de ponto flutuante, para aguardar um número fracionário de segundos. Para atrasos de granularidade mais fina ou apenas inteiros, use as funções sleep_ms() e sleep_us().

A chamada de sleep(), incluindo sleep(0), garante a chamada das funções de callback pendentes.

time.sleep_ms(ms: int) None

Atrasa pelo número de milissegundos fornecido, que deve ser positivo ou 0.

Esta função atrasará por pelo menos o número de milissegundos fornecido, mas pode demorar mais do que isso se outro processamento precisar ocorrer, por exemplo, manipuladores de interrupção ou outras threads. Passar 0 para ms ainda permitirá que esse outro processamento ocorra. Use sleep_us() para atrasos mais precisos.

A chamada de sleep_ms(), incluindo sleep_ms(0), garante a chamada das funções de callback pendentes.

time.sleep_us(us: int) None

Atrasa pelo número de microssegundos fornecido, que deve ser positivo ou 0.

Esta função tenta fornecer um atraso preciso de pelo menos us microssegundos, mas pode demorar mais se o sistema tiver outro processamento de prioridade mais alta a realizar.

time.ticks_ms() int

Retorna um contador crescente de milissegundos com um ponto de referência arbitrário, que dá a volta após algum valor.

O valor de volta não é exposto explicitamente, mas nos referiremos a ele como TICKS_MAX para simplificar a discussão. O período dos valores é TICKS_PERIOD = TICKS_MAX + 1. TICKS_PERIOD é garantidamente uma potência de dois, mas, fora isso, pode diferir de porta para porta. O mesmo valor de período é usado para todas as funções ticks_ms(), ticks_us(), ticks_cpu() (por simplicidade). Assim, essas funções retornarão um valor no intervalo [0 .. TICKS_MAX], inclusive, totalizando TICKS_PERIOD valores. Observe que apenas valores não negativos são usados. Na maior parte das vezes, você deve tratar os valores retornados por essas funções como opacos. As únicas operações disponíveis para eles são as funções ticks_diff() e ticks_add() descritas abaixo.

Observação: Realizar operações matemáticas padrão (+, -) ou operadores relacionais (<, <=, >, >=) diretamente sobre esses valores levará a resultados inválidos. Realizar operações matemáticas e depois passar seus resultados como argumentos para ticks_diff() ou ticks_add() também levará a resultados inválidos dessas últimas funções.

time.ticks_us() int

Exatamente como ticks_ms() acima, mas em microssegundos.

time.ticks_cpu() int

Semelhante a ticks_ms() e ticks_us(), mas com a maior resolução possível no sistema. Isso geralmente são os ciclos da CPU, e é por isso que a função recebe esse nome. Mas não precisa ser um relógio de CPU; alguma outra fonte de tempo disponível em um sistema (por exemplo, um timer de alta resolução) pode ser usada no lugar. A unidade de tempo exata (resolução) desta função não é especificada no nível do módulo time, mas a documentação de uma porta específica pode fornecer informações mais específicas. Esta função é destinada a benchmarking muito fino ou a loops de tempo real muito apertados. Evite usá-la em código portável. Ela está disponível em todas as OpenMV Cams.

time.ticks_add(ticks: int, delta: int) int

Desloca um valor de ticks por um número fornecido, que pode ser positivo ou negativo. Dado um valor ticks, esta função permite calcular o valor de ticks delta ticks antes ou depois dele, seguindo a definição de aritmética modular dos valores de tick (veja ticks_ms() acima). O parâmetro ticks deve ser um resultado direto de uma chamada às funções ticks_ms(), ticks_us() ou ticks_cpu() (ou de uma chamada anterior a ticks_add()). No entanto, delta pode ser um número inteiro arbitrário ou uma expressão numérica. ticks_add() é útil para calcular prazos para eventos/tarefas. (Observação: você deve usar a função ticks_diff() para trabalhar com prazos.)

Exemplos:

# 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

Mede a diferença de ticks entre os valores retornados pelas funções ticks_ms(), ticks_us() ou ticks_cpu(), como um valor com sinal que pode dar a volta.

A ordem dos argumentos é a mesma do operador de subtração, ticks_diff(ticks1, ticks2) tem o mesmo significado que ticks1 - ticks2. No entanto, os valores retornados pelas funções ticks_ms(), etc. podem dar a volta, então usar a subtração diretamente sobre eles produzirá um resultado incorreto. É por isso que ticks_diff() é necessária, ela implementa aritmética modular (ou, mais especificamente, de anel) para produzir o resultado correto mesmo para valores que dão a volta (desde que não estejam muito distantes entre si, veja abaixo). A função retorna um valor com sinal no intervalo [-TICKS_PERIOD/2 .. TICKS_PERIOD/2-1] (essa é uma definição de intervalo típica para inteiros binários com sinal em complemento de dois). Se o resultado for negativo, significa que ticks1 ocorreu mais cedo no tempo do que ticks2. Caso contrário, significa que ticks1 ocorreu depois de ticks2. Isso vale apenas se ticks1 e ticks2 estiverem distantes entre si por no máximo TICKS_PERIOD/2-1 ticks. Se isso não valer, será retornado um resultado incorreto. Especificamente, se dois valores de tick estiverem distantes por TICKS_PERIOD/2-1 ticks, esse valor será retornado pela função. No entanto, se TICKS_PERIOD/2 ticks de tempo real tiverem passado entre eles, a função retornará -TICKS_PERIOD/2 em vez disso, ou seja, o valor do resultado dará a volta para o intervalo negativo de valores possíveis.

Justificativa informal das restrições acima: Suponha que você esteja trancado em uma sala sem nenhum meio de monitorar a passagem do tempo, exceto um relógio padrão de 12 marcações. Então, se você olhar para o mostrador agora e não olhar novamente por mais 13 horas (por exemplo, se cair em um sono longo), quando finalmente olhar de novo, pode parecer que apenas 1 hora se passou. Para evitar esse erro, basta olhar para o relógio regularmente. Sua aplicação deve fazer o mesmo. A metáfora do “sono longo demais” também se aplica diretamente ao comportamento da aplicação: não deixe sua aplicação executar uma única tarefa por tempo demais. Execute as tarefas em etapas e faça a marcação do tempo entre elas.

ticks_diff() foi projetada para acomodar diversos padrões de uso, entre eles:

  • Polling com timeout. Neste caso, a ordem dos eventos é conhecida, e você lidará apenas com resultados positivos de 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
    
  • Agendamento de eventos. Neste caso, o resultado de ticks_diff() pode ser negativo se um evento estiver atrasado:

    # 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)
    

Observação: Não passe valores de time() para ticks_diff(), você deve usar operações matemáticas normais sobre eles. Mas observe que time() pode (e vai) também transbordar. Isso é conhecido como https://en.wikipedia.org/wiki/Year_2038_problem .

time.time() int

Retorna o número de segundos, como um inteiro, desde a Época, assumindo que o RTC subjacente esteja definido e mantido conforme descrito acima. Se um RTC não estiver definido, esta função retorna o número de segundos desde um ponto de referência no tempo específico da porta (para placas embarcadas sem um RTC com bateria de backup, normalmente desde a inicialização ou reset). Se você deseja desenvolver uma aplicação portável em MicroPython, não deve depender desta função para fornecer precisão maior que segundos. Se você precisa de maior precisão, com timestamps absolutos, use time_ns(). Se tempos relativos forem aceitáveis, então use as funções ticks_ms() e ticks_us(). Se você precisa de tempo de calendário, gmtime() ou localtime() sem argumento é uma escolha melhor.

Diferença em relação ao CPython

No CPython, esta função retorna o número de segundos desde a época Unix (1970-01-01 00:00 UTC) como um valor de ponto flutuante, normalmente com precisão de microssegundos. Na OpenMV Cam, ela retorna um inteiro com precisão de um segundo – o hardware não consegue representar simultaneamente um longo intervalo de tempo e precisão de subsegundos em um float – e a época difere conforme a placa (veja Época de tempo acima). Sem um RTC com bateria de backup que tenha sido definido, ela conta, em vez disso, os segundos desde a inicialização/reset.

time.time_ns() int

Semelhante a time(), mas retorna nanossegundos desde a Época, como um inteiro (geralmente um inteiro grande, então alocará na heap).

Construtores

class time.clock

Retorna um objeto clock.

Métodos

tick() None

Inicia o rastreamento do tempo decorrido.

fps() float

Para de rastrear o tempo decorrido e retorna o FPS (quadros por segundo) atual.

Sempre chame tick primeiro antes de chamar esta função.

avg() float

Para de rastrear o tempo decorrido e retorna o tempo médio decorrido atual em milissegundos.

Sempre chame tick primeiro antes de chamar esta função.

reset() None

Reinicia o objeto clock.