delay() 없이 delay() 느낌을 원합니다.

11422 단어 전자 공작Arduino

delay()는 편리하지만


delay() 를 사용하면 그동안 모든 처리가 멈춥니다. 그럼 이제 CPU 가치가치입니다. 파이썬에서 말한다 time.sleep() 라든지입니다.
처리 간격을 조정하거나 뭔가 신세를 질 수 있습니다.

예를 들어, 아래의 L 치카 코드.
매번 쓰고 있다고 생각하기 때문에 조금 변화구인 L치카코드로 했습니다만 뭐 평소의 「1초마다 붙거나 사라지거나」하는 녀석입니다.

블링크
void loop()
{
    static int state1 = HIGH;
    state1 = blink(LED1, state1);
    delay(1000);
}

int blink(int pin, int state)
{
    digitalWrite(pin, state);
    return state = HIGH - state;
}

이웃의 할아버지가 이렇게 말했습니다. "delay() 기분 나쁘다"
물론 이것으로 어렵게 움직입니다. 그러나 지금까지 전혀 신경이 쓰이지 않았습니다만, 무엇이 기분 나쁜가 하면, delay(1000) 의 사이, 완전하게 처리가 정지하고 있는 것입니다. Arduino의 공식 참조에도 이렇게 설명되어 있습니다.

delay()를 사용하면 쉽게 LED를 치카치카 시킬 수 있습니다. 또한 스위치의 바운스 대책을 위해 delay()를 사용하는 스케치도 자주 볼 수 있습니다. 다만, 이러한 delay()의 사용법에는 불리한 점이 있습니다. delay() 실행 중에는 계산이나 핀 조작과 같은 다른 처리가 실질적으로 멈춰 버립니다. delay() 대신 millis() 를 사용하여 시간을 측정하고 타이밍을 제어하는 ​​것이 좋습니다. 숙련된 프로그래머는 스케치가 쉬워지지 않는 한 10ms 이상의 이벤트를 제어하는 ​​데 delay()를 사용하지 않습니다.

인터럽트가 효과적이지만, 진짜로 처리가 멈추는 것 같네요.
뭐야?

숙련된 프로그래머는 스케치가 쉬워지지 않는 한 10ms 이상의 이벤트를 제어하는 ​​데 delay()를 사용하지 않습니다.

아무래도 이웃의 할아버지는 숙련된 프로그래머였던 것 같습니다.
자, 숙련된 프로그래머가 되세요! (땀)

delay() 사용하지 않는 처리로 바꾸어 보았다



아이디어 팁은 공식 참조에서 찾을 수 있습니다.millis() 를 사용하여 시간을 측정하고 타이밍을 제어하면 좋다고 합니다.
힌트를 바탕으로 코딩. 그럼 가자.

no_delay
void loop()
{
    // staticを付けて変数の値を保持します。
    static unsigned char count = 0;
    static unsigned long millis_buf = 0;
    static int state1 = HIGH;
    static int state2 = HIGH;
    static int state3 = HIGH;

    // 現在の経過時間-この待機処理を通過した時間が1000(ms)になるまで待機
    while ((millis() - millis_buf) < 1000)
    {
        ;
    }
    // 上の待機から抜けた時間を格納
    millis_buf = millis();
    Serial.println(millis_buf);

    // カウントを取る
    count++;

    // カウントを1で割った余り0(ここを通る度に処理)
    if ((count % 1) == 0)
    {
        // LEDのON,OFFを反転させる
        state1 = blink(LED1, state1);
    }
}

int blink(int pin, int state)
{
    digitalWrite(pin, state);
    return state = HIGH - state;
}


이런 느낌이 들었습니다.while 를 빠진 후 millis_buf 에 현재 시간을 대입하여 1000ms 주기를 만듭니다.
그리고는 1000ms마다 실시하고 싶은 처리를 아래에 쓰면 훌륭하게 delay() 했어.

이것, 처리의 타이밍 어긋나면 따로따로 움직이는 건가요?



여기 놀아
    if ((count % 1) == 0)
    {
        state1 = blink(LED1, state1);
    }

다음과 같이 추가합니다.
if ((count % 1) == 0)
    {
        state1 = blink(LED1, state1);
    }
    // 2の余りを取る(1秒間隔の、2回に一回処理する)
    if ((count % 2) == 0)
    {
        state2 = blink(LED2, state2);
    }
    // 4の余りを取る(4回に一回処理)
    if ((count % 4) == 0)
    {
        state3 = blink(LED3, state3);
    }
count 변수는 일련의 처리 한 주기마다 증가됩니다.
그렇다면 if문의 내용을 만나면 일정 주기 안에서 임의의 타이밍으로 다른 처리를 할 수 있군요!

2진수 카운터 폭탄





네, 간단하게 2진수 카운터의 완성~!

우선 알기 쉽게 1000ms를 그대로 베타 썼습니다만, 100ms로 루프를 붕 돌려 10회 돌릴 때마다 처리를 하면 위와 같이 1초마다, 2초마다, 4초마다 동작시킬 수 있습니다.
이런 느낌으로 다시 씁니다.
    // さっき1000msだったところを100msに変更
    while ((millis() - millis_buf) < 100)
    {
        ;
    }
    // こっち側が1秒間に10回回るようになる
    millis_buf = millis();
    Serial.println(millis_buf);

    count++;

    // カウントを10で割った余り0(ここを通る度に処理)
    if ((count % 10) == 0)
    {
        state1 = blink(LED1, state1);
    }
    if ((count % 20) == 0)
    {
        state2 = blink(LED2, state2);
    }
    if ((count % 40) == 0)
    {
        state3 = blink(LED3, state3);
    }


이렇게 하면 if문 속의 나누는 수를 보다 세세하게 조정할 수 있으므로, 사용하는 마이크로컴퓨터의 처리 능력이나 처리 내용에 맞추어 응용이 유리할 것 같습니다.
지금 개발하고 있는 프로그램으로 정확히 어떤 처리가 하고 싶었기 때문에 좋은 공부가 되었습니다. 숙련된 프로그래머에게 한 걸음 더 가까웠습니다!

끝에



즉 폴링이잖아.

좋은 웹페이지 즐겨찾기