수색…


통사론

  • 부호없는 long millis ()

  • 부호없는 긴 마이크로 ()

  • void 지연 (부호없는 긴 밀리 초)

  • void delayMicroseconds (부호 없음 long 마이크로 초)

  • 해당 클래스의 생성자와 연산자에 대해서는 elapsedMillis 헤더 를 참조하십시오. 간단히 말해서 :

    • elapsedMillis elapsedMillisObject; 생성 된 이후 또는 다른 명시 적으로 설정된 특정 시점 이후의 시간을 추적하는 객체를 생성합니다.
    • elapsedMillisObject = 0; 객체에 의해 추적 된 시간을 "지금부터"로 재설정합니다.
    • 부호없는 long deltaT = elapsedMillisObject; 추적 시간을 살펴 봅니다.
    • elapsedMillisObject + = 및 - = 예상대로 작동합니다.

비고

차단 대 비 차단 코드

매우 간단한 스케치의 경우 delay()delayMicroseconds() 사용하여 차단 코드를 작성하는 것이 적절할 수 있습니다. 상황이 더욱 복잡 해지면 이러한 함수를 사용하면 몇 가지 단점이 생길 수 있습니다. 이들 중 일부는 다음과 같습니다.

  • CPU 시간 낭비 : 더 복잡한 스케치는 LED 깜박임 기간이 끝나기를 기다리는 동안 다른 것을 위해 CPU가 필요할 수 있습니다.
  • 예상치 못한 지연 : delay() 가 명시 적으로 호출되지 않은 서브 루틴, 예를 들어 포함 된 라이브러리에서 호출 될 때.
  • 지연 중에 발생하는 누락 된 이벤트 및 인터럽트 처리기에서 처리하지 않는 이벤트 (예 : 폴링 된 단추 누름) : 100ms 동안 단추가 눌러 지지만 delay(500) 으로 delay(500) 섀도 잉 될 수 있습니다.

구현 세부 사항

millis() 일반적으로 1 kHz보다 훨씬 빠른 속도로 실행되는 하드웨어 타이머를 사용합니다. millis() 가 호출되면, 구현은 어떤 값을 리턴하지만 실제로 얼마나 오래되었는지 알지 못합니다. "현재"밀리 초가 방금 시작되었거나 해당 함수 호출 직후에 종료 될 수 있습니다. 즉, millis() 두 결과 간의 차이를 계산할 때 거의 0에서 거의 1 밀리 초 사이의 값을 가질 수 있습니다. 더 높은 정밀도가 필요한 경우 micros() 사용하십시오.

elapsedMillis 의 소스 코드를 살펴보면 내부적으로 millis() 를 사용하여 두 지점을 비교하는 것으로 나타 elapsedMillis 효과도 있습니다. 다시 말하지만, 동일한 라이브러리에서 더 높은 정밀도를위한 대체 elapsedMicros 가 있습니다.

지연 (blinky with delay) 차단

LED를 깜박이는 가장 직접적인 방법 중 하나는 켜기, 조금 기다린 후 끄고 다시 기다리고 끝없이 반복하는 것입니다.

// set constants for blinking the built-in LED at 1 Hz
#define OUTPIN LED_BUILTIN
#define PERIOD 500

void setup()
{
  pinMode(OUTPIN, OUTPUT);      // sets the digital pin as output
}

void loop()
{
  digitalWrite(OUTPIN, HIGH);   // sets the pin on
  delayMicroseconds(PERIOD);        // pauses for 500 miliseconds      
  digitalWrite(OUTPIN, LOW);    // sets the pin off
  delayMicroseconds(PERIOD);        // pauses for 500 milliseconds

  // doing other time-consuming stuff here will skew the blinking
}

그러나 위의 예 에서처럼 대기하면 CPU주기가 낭비됩니다. 특정 시점을 기다리는 루프에 그냥 있기 때문입니다. 이것이 millis() 또는 elapsedMillis 사용하는 비 차단 방식이 하드웨어의 많은 기능을 소모하지 않는다는 점에서 더 좋습니다.

elapsedMillis 라이브러리 (및 클래스)로 블로킹 (blinky)

elapsedMillis 라이브러리 는 클래스가 만들어 지거나 경과 된 시간을 추적하는 동일한 이름을 클래스에 제공합니다.

#include <elapsedMillis.h>

#define OUTPIN LED_BUILTIN
#define PERIOD 500

elapsedMillis ledTime;

bool ledState = false;

void setup() 
{                
  // initialize the digital pin as an output.
  pinMode(OUTPIN, OUTPUT);     
}

void loop()
{
    if (ledTime >= PERIOD) 
    {                
        ledState = !ledState;
        digitalWrite(OUTPIN, ledState);
        ledTime = 0;
    }
    // do other stuff here
}

이 예제에서 LED 핀이 토글되었을 때 ledTime 객체가 0으로 지정되었음을 알 수 있습니다. 얼핏보기에는 놀랄만 한 일은 아니지만 더 많은 시간이 걸리면 효과가 있습니다.

ledTimePERIOD 를 750 밀리 초 후에 비교하는 경우를 생각해보십시오. 그런 다음 ledTime 을 0으로 설정하면 다음의 모든 토글 조작이 250ms "늦게"수행됩니다. 대조적으로, PERIODledTime 에서 ledTime , LED는 짧은 기간을 보게되고 아무 일도없는 것처럼 계속 깜박입니다.

millis ()로 blinky 비 블로킹

arduino 문서의 예제와 매우 비슷합니다.

// set constants for blinking the built-in LED at 1 Hz
#define OUTPIN LED_BUILTIN
#define PERIOD 500  // this is in milliseconds

int ledState = LOW;

// millis() returns an unsigned long so we'll use that to keep track of time
unsigned long lastTime = 0;

void setup() {
  // set the digital pin as output:
  pinMode(OUTPIN, OUTPUT);
}

void loop() {
  unsigned long now = millis();
  if (now - lastTime >= PERIOD) // this will be true every PERIOD milliseconds
  {
    lastTime = now;
    if (ledState == LOW)
    {
      ledState = HIGH;
    }
    else
    {
      ledState = LOW;
    }
    digitalWrite(OUTPIN, ledState);
  }

  // now there's lots of time to do other stuff here
}

이런 방식으로 millis() 를 사용하여 - 비 - 블로킹 방식으로 작업 시간을 elapsedMillis 일은 - 자주 필요로하는 일이기 때문에이를 위해 elapsedMillis 라이브러리 사용을 고려하십시오.

elapsedMillis 및 elapsedMicros를 사용하여 일정 기간 측정

#include <elapsedMillis.h>

void setup() {
  Serial.begin(115200);
  elapsedMillis msTimer;
  elapsedMicros usTimer;

  long int dt = 500;
  delay(dt);

  long int us = usTimer;
  long int ms = msTimer;

  Serial.print("delay(");Serial.print(dt);Serial.println(") took");
  Serial.print(us);Serial.println(" us, or");
  Serial.print(ms);Serial.println(" ms");
}

void loop() {
}

이 예제에서 elapsedMillis 객체와 elapsedMicros 객체는 무언가가 걸린 시간을 측정하는 데 사용됩니다. 시간을 계산하려는 표현식이 실행되기 직전에 객체를 생성하고 나중에 값을 가져 오는 방식으로 사용합니다. 약간 다른 결과가 표시되지만 밀리 초 결과는 1 밀리 초 이상 벗어나지 않습니다.

지연없이 1 개 이상의 작업 ()

서로 다른 간격으로 반복적으로 실행하는 태스크가 두 개 이상인 경우이 예제를 시작점으로 사용하십시오.

unsigned long intervals[] = {250,2000}; //this defines the interval for each task in milliseconds
unsigned long last[] = {0,0};           //this records the last executed time for each task

void setup() {
  pinMode(LED_BUILTIN, OUTPUT); //set the built-it led pin as output
  Serial.begin(115200);         //initialize serial
}

void loop() {
  unsigned long now = millis();
  if(now-last[0]>=intervals[0]){ last[0]=now; firstTask(); }
  if(now-last[1]>=intervals[1]){ last[1]=now; secondTask(); }
  
  //do other things here
}

void firstTask(){
  //let's toggle the built-in led
  digitalWrite(LED_BUILTIN, digitalRead(LED_BUILTIN)?0:1);
}

void secondTask(){
  //say hello
  Serial.println("hello from secondTask()");
}

다른 작업을 추가하여 매 15 초마다 실행하려면 변수 intervals 연장하고 last :

unsigned long intervals[] = {250,2000,15000};
unsigned long last[] = {0,0,0};

그런 다음 if 문을 추가하여 새 작업을 실행합니다. 이 예제에서는 이름을 thirdTask 지정했습니다.

if(now-last[2]>=intervals[2]){ last[2]=now; thirdTask(); }

마지막으로 함수를 선언하십시오.

void thirdTask(){
  //your code here
}


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow