how to chase your own tail :
Last year I investigated delayMicroseconds() for small values. That lead to a patch for the function
See - http://forum.arduino.cc/index.php/topic,132983.0.html -
Today I wrote a small program how delayMicroseconds() behaves in practice for values from 1-2000. Above 2000 micros, it is advised to use
delay(whole millis)
delay(remaindermicros);
The reason why I investigated this is because delayMicoseconds() is often used in handshakes with sensors (e.g. DHT22).
Errors in delayMicoseconds() might add up during a handshake which can cause hard to debug failures.
I started writing a simple test sketch in which I use micros() to test the timing of delayMicroseconds().
True, this is not a hardware timer accuracy but it gives a first indication.
As micros() returns always a multiple of four I decided to call delayMicroseconds four times which makes the math a bit easier.
//
// FILE: test_delay_microseconds.ino
// AUTHOR: Rob Tillaart
// VERSION: 2013-08-31
// PURPOSE: test accuracy of delayMicroseconds()
// URL:
//
// Released to the public domain
//
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.println();
for (int i=1; i<2000; i+=10)
{
uint32_t start = micros();
delayMicroseconds(i);
delayMicroseconds(i);
delayMicroseconds(i);
delayMicroseconds(i);
uint32_t stop = micros();
int diff = (stop - start)/4;
int delta = diff - i;
Serial.print(i);
Serial.print("\t");
Serial.print(diff);
Serial.print("\t");
Serial.print(delta);
Serial.print("\t");
Serial.println(100.0*delta/i);
}
}
void loop(){}
The output (the comma is decimal separator)
1 2 1 100
11 12 1 9,09
21 23 2 9,52
31 33 2 6,45
41 44 3 7,32
51 55 4 7,84
61 67 6 9,84
71 77 6 8,45
81 86 5 6,17
91 97 6 6,59
101 109 8 7,92
111 119 8 7,21
121 129 8 6,61
131 140 9 6,87
141 152 11 7,8
151 160 9 5,96
161 173 12 7,45
171 182 11 6,43
181 195 14 7,73
191 204 13 6,81
201 216 15 7,46
211 226 15 7,11
221 238 17 7,69
231 247 16 6,93
241 258 17 7,05
251 269 18 7,17
261 280 19 7,28
271 290 19 7,01
281 302 21 7,47
291 312 21 7,22
301 324 23 7,64
311 334 23 7,4
321 343 22 6,85
331 357 26 7,85
341 368 27 7,92
351 378 27 7,69
361 387 26 7,2
371 397 26 7,01
381 408 27 7,09
391 413 22 5,63
401 418 17 4,24
411 428 17 4,14
421 438 17 4,04
431 449 18 4,18
441 460 19 4,31
451 469 18 3,99
461 480 19 4,12
471 490 19 4,03
481 500 19 3,95
491 510 19 3,87
501 519 18 3,59
511 529 18 3,52
521 540 19 3,65
531 550 19 3,58
541 559 18 3,33
551 569 18 3,27
561 579 18 3,21
571 591 20 3,5
581 600 19 3,27
591 610 19 3,21
601 620 19 3,16
611 632 21 3,44
621 641 20 3,22
631 651 20 3,17
641 661 20 3,12
651 671 20 3,07
661 682 21 3,18
671 691 20 2,98
681 702 21 3,08
691 711 20 2,89
701 721 20 2,85
711 732 21 2,95
721 741 20 2,77
731 751 20 2,74
741 761 20 2,7
751 771 20 2,66
761 781 20 2,63
771 791 20 2,59
781 802 21 2,69
791 811 20 2,53
801 822 21 2,62
811 831 20 2,47
821 841 20 2,44
831 853 22 2,65
841 861 20 2,38
851 871 20 2,35
861 882 21 2,44
871 892 21 2,41
881 903 22 2,5
891 913 22 2,47
901 923 22 2,44
911 933 22 2,41
921 942 21 2,28
931 953 22 2,36
941 962 21 2,23
951 973 22 2,31
961 981 20 2,08
971 993 22 2,27
981 1003 22 2,24
991 1014 23 2,32
1001 1024 23 2,3
1011 1035 24 2,37
1021 1045 24 2,35
1031 1055 24 2,33
1041 1065 24 2,31
1051 1076 25 2,38
1061 1086 25 2,36
1071 1097 26 2,43
1081 1105 24 2,22
1091 1115 24 2,2
1101 1126 25 2,27
1111 1137 26 2,34
1121 1147 26 2,32
1131 1156 25 2,21
1141 1167 26 2,28
1151 1177 26 2,26
1161 1187 26 2,24
1171 1197 26 2,22
1181 1207 26 2,2
1191 1217 26 2,18
1201 1227 26 2,16
1211 1237 26 2,15
1221 1247 26 2,13
1231 1257 26 2,11
1241 1265 24 1,93
1251 1277 26 2,08
1261 1287 26 2,06
1271 1297 26 2,05
1281 1307 26 2,03
1291 1317 26 2,01
1301 1327 26 2
1311 1337 26 1,98
1321 1349 28 2,12
1331 1356 25 1,88
1341 1367 26 1,94
1351 1376 25 1,85
1361 1388 27 1,98
1371 1399 28 2,04
1381 1408 27 1,96
1391 1419 28 2,01
1401 1428 27 1,93
1411 1439 28 1,98
1421 1448 27 1,9
1431 1459 28 1,96
1441 1469 28 1,94
1451 1479 28 1,93
1461 1488 27 1,85
1471 1498 27 1,84
1481 1509 28 1,89
1491 1519 28 1,88
1501 1528 27 1,8
1511 1539 28 1,85
1521 1548 27 1,78
1531 1558 27 1,76
1541 1569 28 1,82
1551 1579 28 1,81
1561 1590 29 1,86
1571 1598 27 1,72
1581 1609 28 1,77
1591 1620 29 1,82
1601 1630 29 1,81
1611 1638 27 1,68
1621 1649 28 1,73
1631 1659 28 1,72
1641 1669 28 1,71
1651 1680 29 1,76
1661 1690 29 1,75
1671 1700 29 1,74
1681 1710 29 1,73
1691 1718 27 1,6
1701 1728 27 1,59
1711 1740 29 1,69
1721 1750 29 1,69
1731 1760 29 1,68
1741 1768 27 1,55
1751 1780 29 1,66
1761 1790 29 1,65
1771 1800 29 1,64
1781 1810 29 1,63
1791 1820 29 1,62
1801 1830 29 1,61
1811 1840 29 1,6
1821 1850 29 1,59
1831 1860 29 1,58
1841 1870 29 1,58
1851 1881 30 1,62
1861 1890 29 1,56
1871 1900 29 1,55
1881 1910 29 1,54
1891 1920 29 1,53
1901 1932 31 1,63
1911 1942 31 1,62
1921 1952 31 1,61
1931 1962 31 1,61
1941 1971 30 1,55
1951 1980 29 1,49
1961 1992 31 1,58
1971 2001 30 1,52
1981 2011 30 1,51
1991 2022 31 1,56
What we see is there is a slowly increasing absolute error (3rd column) which is a decreasing relative error (4rd column).
When putting it in a graph one can estimate the error by 2 relative simple linear formulas.
0..250 => error = 0.0679x;
250..2000 => error = 13 + 0.0097x;
to be continued...
update: I've been chasing my own tail as the printing of the numbers in the test program is done in parallel with the "test", so this is affecting the measurement.
I could see this by removing the print statements and checked the cumulative error (abs & rel) for the range [0..2000].
Lesson learned:
Still the above does mean that if a handshake is implemented with delayMicroseconds() and there is a (busy) interrupt in the background, either due to printing or some other sensor increasing a counter every 10 usec, it might be worth to check the timing of the handshake.m
For larger micro delays it might be wiser to use a tight loop as its max abs error is 4 uS (UNO16MHz) and it is more interrupt proof than delayMicroseconds.
* *uint32_t udelay = 300; uint32_t start = micros(); while (micros() - start >= udelay);* *