Skip to content

delay() duration #226

@fulda1

Description

@fulda1

Hi,

yesterday I did some easy application, which needs to generate 2 millisecond pulse. Very easy, so I used:

digitalWrite(MyPin, HIGH);
delay(2);
digitalWrite(MyPin, LOW);

Nothing special, but I was surprised, that pulse is not 2ms, but 1ms > pulse > 2ms. So I go to delay() implementation and found, that it count number of milliseconds from SysTick (System Counter). But the first millisecond is not properly rounded.

To demonstrate issue, let us have time scale like following. It present 2 milliseconds of time, each millisecond is split to "J" tenths.

0                             1                             2
|                             |                             |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
A  B  C  D  E  F  G  H  I  J  A  B  C  D  E  F  G  H  I  J  A

situation - when delay(2) is called in time 0.A, it will take almost 2ms. in case delay(2) is called in time 0.J, it will take 1.1 ms only.

so, looking how to "fix" it. It seems, it will be easy fix like:

  uint64_t m0 = GetTick();
  __IO uint32_t u0 = SysTick->CNT;
  uint64_t m1 = GetTick();
  __IO uint32_t u1 = SysTick->CNT;   //may be a interruption

  if (m1 != m0) {
    do {              // full millisecond
      yield();
    } while (getCurrentMillis() - m1 < ms);
    do {              // remaining partial millisecond
      yield();
    } while ((SysTick->CNT < u1 ) && (getCurrentMillis() - m1 < (ms + 1)));
  } else {
    do {              // full millisecond
      yield();
    } while (getCurrentMillis() - m0 < ms);
    do {              // remaining partial millisecond
      yield();
    } while ((SysTick->CNT < u0 ) && (getCurrentMillis() - m0 < (ms + 1)));
  }

I need to check and spent some time on it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions