3.3. 가상 타이머

타이밍 페이지는 타임스탬프와 time.ticks_diff() 로 구동되는 논블로킹 루프를 다루었습니다. 가상 타이머는 그 반대편입니다. 소프트웨어가 런타임에게 어떤 함수를 일정에 따라 호출해 달라고 요청하면, 런타임이 스크립트가 직접 클럭을 확인할 필요 없이 콜백을 호출합니다.

3.3.1. machine.Timer 클래스

machine.Timer 는 가상 타이머를 생성합니다. 포트 간 일관된 동작을 위해서는 특수 id -1 이 필요하며, 나머지 – period, mode, callback – 는 모두 키워드 인수로 설정합니다:

from machine import Timer

def tick(t):
    print("tick")

tim = Timer(-1)
tim.init(period=100, callback=tick)   # 10 Hz

콜백은 여느 평범한 함수 호출처럼 호출됩니다 – 어떤 특별한 제약 없이 객체를 할당하고, print() 하고, 다른 라이브러리 코드를 호출할 수 있습니다.

3.3.2. 주기적 및 일회성

두 가지 모드를 사용할 수 있습니다:

  • Timer.PERIODIC (기본값). 콜백은 deinit()가 호출되거나 타이머가 다시 초기화될 때까지 period 밀리초마다 영원히 발생합니다.

  • Timer.ONE_SHOT. 콜백은 init() 이후 period 밀리초 뒤에 한 번 발생하고, 그 후 타이머가 멈춥니다.

Timer(-1).init(mode=Timer.ONE_SHOT, period=2000, callback=fire)

deinit() 는 주기적 타이머를 멈추고 대기 중인 콜백을 취소합니다:

tim.deinit()

3.3.3. 타이머를 사용할 때

가상 타이머와 타이밍ticks_diff() 폴링 패턴은 같은 문제를 반대 방향에서 해결합니다. 폴링 루프는 매 반복마다 클럭을 확인하여 충분한 시간이 지났을 때 행동하고, 타이머는 충분한 시간이 지났을 때 스크립트를 깨우도록 런타임에게 요청합니다.

  • 폴링 ticks_diff. 모든 것이 한 곳에 모여 있습니다 – 루프가 타이밍을 소유하고, 추적할 추가 콜백이 없습니다. 여러 시간 기반 작업을 함께 묶는 짧고 명확하게 정의된 작업에 가장 적합합니다.

  • 가상 타이머. 스케줄을 루프 본문 밖으로 옮깁니다. 주기적 작업이 메인 흐름과 독립적일 때(하트비트 LED, 주기적 센서 샘플 등) 가장 적합하며, 메인 루프가 다른 작업에 시간을 쓸 수 있게 해줍니다.

두 접근 방식 모두 동일한 기저 클럭을 사용하며 1밀리초 이상의 주기에서 동일한 정확도를 제공합니다. 어느 쪽도 정밀한 핀 토글링이나 1밀리초 미만의 파형 생성에는 적합하지 않습니다 – 콜백 지연 시간은 나노초가 아니라 스케줄러 틱 정도이기 때문입니다.