잘 알려진 아두 이노 함수는 매개 변수로 지정된 밀리 초의 양에 대한 프로그램을 일시 정지delay()
입니다.
millis()
, 한편,프로그램 시작 이후 경과 한 밀리 초의 양을 반환 함수이다.
언뜻보기에이 기능의 유용성을 의심 할 수 있습니다. 사실 많은 시나리오에서 매우 유용하며 종종delay()
을 완전히”대체”합니다. 먼저millis()
을delay()
과 거의 동일하게 사용할 수있는 방법을 살펴 보겠습니다.
타이밍 문제는 종종 프로그래밍에 존재합니다.
지연과 같은 밀리스 사용()
int period = 1000;unsigned long time_now = 0;void setup() {Serial.begin(115200);}void loop() {time_now = millis(); Serial.println("Hello"); while(millis() < time_now + period){//wait approx. ms}}
각 루프 반복이 끝날 때 코드를 1000 밀리 초 동안 일시 중지하려면 위의 코드는 약간 어리 석습니다. 대신delay(1000)
을 사용할 수 있습니다. 위의 코드와 끝에delay(1000)
이 있는 코드의 유일한 차이점은 위의 코드의 루프가 매초마다 매우 정확하게 실행된다는 것입니다. delay(1000)
이 있는 코드의 루프는Serial.println("Hello")
를 실행하는 데 약간의 시간이 걸리기 때문에 조금 덜 자주 실행됩니다.
왜 지연()대신 밀리()를 사용합니까?
이제delay()
에 비해millis()
의 두 가지 이점을 살펴볼 것입니다.
정확한 타이밍
우리가 논의 할 첫 번째 장점은 정확한 타이밍입니다. 코드 현명한,우리는 마지막 장에서 이것을 다루었습니다. millis()
을 사용하면 실행 시간에 관계없이 루프가 원하는만큼 자주 실행되도록 할 수 있습니다(분명히 실행 시간이 원하는 기간보다 짧은 시간 인 한). delay()
의 경우 루프 실행 시간이 얼마인지 모르기 때문에 불가능합니다.
이와 같은 정확한 타이밍은 특정 주파수에서 샘플링하거나 필터를 실행할 때 매우 유용합니다.
비 차단
millis()
의 다른 이점은”대기 중”동안 코드를 실행하는 것을 방해하지 않는다는 것입니다.
우리가 인쇄 할 가정 해 봅시다”안녕하세요”직렬을 통해 각 초마다 한 번 그 동안 다른 일을하는 동안. 전체 코드를 일시 중지하므로delay()
에서는 이 작업을 수행할 수 없습니다. 여기에 우리가 이것을 할 수있는 한 가지 방법이 있습니다:
int period = 1000;unsigned long time_now = 0;void setup() {Serial.begin(115200);}void loop() {if(millis() >= time_now + period){time_now += period;Serial.println("Hello");} //Run other code}
이 코드 덩어리는 직렬 위에 인쇄하지 않을 때 나머지 프로그램을 차단하지 않는다는 점을 제외하고는 첫 번째 청크와 매우 유사합니다.
예:간단한 스케줄러
특정 비트의 텍스트를 서로 다른 간격으로 인쇄하는 스케줄러를 만드는 간단한 예제를 작성해 보겠습니다.
#define INTERVAL_MESSAGE1 5000#define INTERVAL_MESSAGE2 7000#define INTERVAL_MESSAGE3 11000#define INTERVAL_MESSAGE4 13000unsigned long time_1 = 0;unsigned long time_2 = 0;unsigned long time_3 = 0;unsigned long time_4 = 0;void print_time(unsigned long time_millis);void setup() {Serial.begin(115200);}void loop() {if(millis() >= time_1 + INTERVAL_MESSAGE1){time_1 +=INTERVAL_MESSAGE1;print_time(time_1);Serial.println("I'm message number one!");} if(millis() >= time_2 + INTERVAL_MESSAGE2){time_2 +=INTERVAL_MESSAGE2;print_time(time_2);Serial.println("Hello, I'm the second message.");} if(millis() >= time_3 + INTERVAL_MESSAGE3){time_3 +=INTERVAL_MESSAGE3;print_time(time_3);Serial.println("My name is Message the third.");} if(millis() >= time_4 + INTERVAL_MESSAGE4){time_4 += INTERVAL_MESSAGE4;print_time(time_4);Serial.println("Message four is in the house!");}}void print_time(unsigned long time_millis){Serial.print("Time: ");Serial.print(time_millis/1000);Serial.print("s - ");}
직렬 모니터의 처음 60 초는 다음과 같습니다:
이 코드에서 실행을 동기화 할 수있는 좋은 쉬운 방법입니다. 다른 코드도 동시에 실행할 수 있습니다.
마이크로()와 넘쳐
delay()
처럼delayMicroseconds()
이라는 마이크로 초 버전이 있습니다. 더 나은 해상도가 필요한 경우micros()
이 갈 길일 수 있습니다.
그러나micros()
은millis()
의 50 일에 비해 약 70 분 후에 오버플로됩니다. 즉,함수의 반환 값이 0 에서 모두 시작됩니다.
더 중요한 것은 오버플로 문제를 모두 피할 수있는 방법을 배우려면이 블로그 게시물을 읽으십시오.
요약
millis()
및micros()
은 타이밍 작업을 처리 할 때 사용할 수있는 정말 편리한 기능입니다. 당신이 이것을 인식하지 못한다면,당신은delay()
을 대신 사용하게 될 수도 있습니다.
더 아두 이노 팁&트릭,우리의 아두 이노 자습서 블로그 카테고리를 확인하십시오. 뿐만 아니라 미래에 더 아두 이노 관련 콘텐츠에 대한 계속 지켜봐 주시기 바랍니다!