{"id":8792,"date":"2023-04-24T09:24:35","date_gmt":"2023-04-24T07:24:35","guid":{"rendered":"https:\/\/deepbluembedded.com\/?p=8792"},"modified":"2023-08-17T23:50:20","modified_gmt":"2023-08-17T20:50:20","slug":"arduino-delaymicroseconds-function-tutorial","status":"publish","type":"post","link":"https:\/\/deepbluembedded.com\/arduino-delaymicroseconds-function-tutorial\/","title":{"rendered":"Arduino delayMicroseconds() Function Tutorial"},"content":{"rendered":"\n

In this tutorial, you’ll learn how to use the Arduino delayMicroseconds() function<\/strong> and how it actually works. We’ll also investigate the accuracy <\/strong>of the Arduino delayMicroseconds() function and do some measurements to reach its fundamental limitations of it. And we’ll discuss what would be a better alternative if needed by your application.<\/p>\n\n\n\n

Without further ado, let’s get right into it!<\/p>\n\n\n

Table of Contents<\/h2>\n
    \n
  1. The Need For delayMicroseconds in Arduino<\/a>\n\n<\/li>\n
  2. Arduino delayMicroseconds() Function<\/a>\n\n<\/li>\n
  3. Arduino delayMicroseconds Example<\/a>\n\n\n\n<\/li>\n\n<\/li>\n\n<\/li>\n\n<\/li>\n\n
  4. Arduino delayMicroseconds Accuracy Tests<\/a>\n\n\n<\/li>\n\n
  5. Concluding Remarks<\/a>\n<\/li><\/ol>\n\n\n
    \n\n\n

    The Need For delayMicroseconds in Arduino<\/strong><\/h2>\n\n\n

    In a previous tutorial, we’ve discussed in detail the Arduino delay() function<\/strong><\/a> and how to use it in your Arduino projects to generate time delays in milliseconds and up to 25 days. But in this tutorial, we’ll go down to very precise time delay intervals generation down to 1\u00b5s and measure the accuracy of the Arduino delayMicroseconds built-in function.<\/p>\n\n\n\n

    Occasionally, you might need to insert a very short time delay to achieve certain functionality for your Arduino projects. Things like short pulse generation, triggering a sensor or external electronic circuit, or forcing the CPU to wait for a short time period before attempting to execute a certain piece of logic.<\/p>\n\n\n\n

    Despite the fact that using a delay function is not generally preferred, it’s still a very popular option for various use cases. And it can be acceptable as long as it’s a few \u00b5s time delay.<\/p>\n\n\n\n


    \n\n\n

    Arduino delayMicroseconds() Function<\/strong><\/h2>\n\n\n

    Description<\/strong><\/p>\n\n\n\n

    The delayMicroseconds()<\/code> function pauses the program for the amount of time (in microseconds) specified as a parameter. There are 1000 microseconds in a millisecond and 1,000,000 microseconds in a second.<\/p>\n\n\n\n

    Syntax<\/strong><\/p>\n\n\n\n

    delayMicroseconds(us);<\/pre>\n\n\n\n

    <\/p>\n\n\n\n

    Parameters<\/strong><\/p>\n\n\n\n

    us<\/code>: the number of microseconds to pause. Allowed data types: unsigned int<\/code><\/p>\n\n\n

    \n
    \u2755 Note<\/div>\n\n\n

    Currently, the largest value that will produce an accurate delay is 16383. Larger values can produce an extremely short delay. This could change in future Arduino releases. For delays longer than a few thousand microseconds, you should use the delay()<\/code> function instead.<\/p>\n\n<\/div><\/div>\n\n\n


    \n\n\n

    Arduino delayMicroseconds Example<\/strong><\/h2>\n\n\n

    Now, we’ll test the delayMicroseconds() function with a very simple short pulse generation example.<\/p>\n\n\n

    Short Pulse Generation With delayMicroseconds<\/h3>\n\n\n

    We’ll drive an Arduino output pin to HIGH<\/strong> and insert a short delay<\/strong> of 100\u00b5s<\/strong>, and then drive it back to LOW<\/strong>. And the resulting short pulse will be measured with an oscilloscope to make sure it has “nearly” the desired pulse width of 100\u00b5s.<\/p>\n\n\n

    Example Code<\/h4>\n\n\n

    Here is the full code listing for this example.<\/p>\n\n\n\n

    \/*\n * LAB Name: Arduino delayMicroseconds Example\n * Author: Khaled Magdy\n * For More Info Visit: www.DeepBlueMbedded.com\n*\/\n\n#define TEST_PIN 8\n\nvoid setup()\n{\n  pinMode(TEST_PIN, OUTPUT);\n}\n\nvoid loop()\n{\n  digitalWrite(TEST_PIN, HIGH);\n  delayMicroseconds(100); \/\/ Delay for 100us\n  digitalWrite(TEST_PIN, LOW);\n  \/\/ Delay Between Pulses\n  delay(100); \/\/ Delay for 100ms\n}<\/pre>\n\n\n\n

    <\/p>\n\n\n

    Code Explanation<\/h4>\n\n\n

    The code example simply sets pin 8 to be output and sends output signal High and Low with 100\u00b5s time delay after each state change.<\/p>\n\n\n\n

    setup()<\/strong><\/p>\n\n\n\n

    in the setup()<\/code> function, we initialize the digital IO pin 8 to be an OUTPUT<\/code> pin.<\/p>\n\n\n\n

    loop()<\/strong><\/p>\n\n\n\n

    in the loop()<\/code> function, we use the digitalWrite()<\/code> function to set the pin state to high and low. And we also use the delayMicroseconds() function to insert a 100\u00b5s time delay after each state change. And we also insert a 100ms time delay after each pulse.<\/p>\n\n\n

    Simulation<\/h4>\n\n\n

    Here is the simulation result for this project on the Proteus simulator (it can be helpful if you don’t have an oscilloscope in your lab yet).<\/p>\n\n\n\n

    \"Arduino-delayMicroseconds-Example-Simulation\"<\/figure>\n\n\n\n

    <\/p>\n\n\n\n

    The resulting pulse is nearly 100\u00b5s as we expect with a slight error of around 1.5\u00b5s.<\/p>\n\n\n

    \n
    ???? Also Read<\/div>\n\n
    \n
    \n\n
    \"Arduino<\/a><\/figure>\n\n<\/div><\/div><\/div>\n\n
    \n
    Arduino Proteus Simulation Guide<\/a><\/div>\n\n\n

    This article will give more in-depth information about using proteus ISIS for Arduino projects simulation.<\/p>\n\n<\/div><\/div><\/div>\n<\/div>\n<\/div><\/div>\n\n

    Testing Results<\/h4>\n\n\n

    Here is the result of testing this project on my Arduino UNO board as captured by my DSO (digital storage oscilloscope). It’s nearly the same as what we’ve seen in the simulation environment.<\/p>\n\n\n\n

    \"Arduino-delayMicroseconds-Example-Test\"<\/figure>\n\n\n\n

    <\/p>\n\n\n

    Interesting Finding<\/h4>\n\n\n

    The behavior I’ll describe here is consistent and easily observable in both simulation environment and in real-world testing. Which is a significant fluctuation in the resulting pulse width (around 10\u00b5s), and it’s sporadic in time.<\/p>\n\n\n\n

    It turned out to be due to having interrupts that pause the delayMicroseconds()<\/code> function execution causing it to take more time than expected in a non-deterministic way. One solution can be to disable interrupts before the “short microseconds delay” and re-enable interrupts afterward. Which is not recommended actually. But for the sake of testing, I’ll modify the code and run the test again.<\/p>\n\n\n\n

    Here is the modified code example.<\/p>\n\n\n\n

    \/*\n * LAB Name: Arduino delayMicroseconds Modified Example\n * Author: Khaled Magdy\n * For More Info Visit: www.DeepBlueMbedded.com\n*\/\n\n#define TEST_PIN 8\n\nvoid setup()\n{\n  pinMode(TEST_PIN, OUTPUT);\n}\n\nvoid loop()\n{\n  noInterrupts(); \/\/ Disable Interrupts\n  digitalWrite(TEST_PIN, HIGH);\n  delayMicroseconds(100); \/\/ Delay for 100us\n  digitalWrite(TEST_PIN, LOW);\n  interrupts();  \/\/ Re-Enable Interrupts\n  \/\/ Delay Between Pulses\n  delay(100); \/\/ Delay for 100ms\n}<\/pre>\n\n\n\n

    <\/p>\n\n\n\n

    After running the example code above, it did eliminate the sporadic fluctuation in the delay microseconds period (pulse width). But as stated earlier, disabling interrupts for critical sections in your code is something that you need to be very careful with or avoid as much as possible.<\/p>\n\n\n\n


    \n\n\n

    Arduino delayMicroseconds Accuracy Tests<\/strong><\/h2>\n\n\n

    In this section, we’ll do some further test procedures to measure the accuracy of the Arduino delayMicroseconds function.<\/p>\n\n\n

    delayMicroseconds Accuracy Measurement Test1<\/h3>\n\n\n

    In this testing procedure, we’ll use the built-in timer-based micros() function to find out the execution time of the delay generated by the delayMicroseconds function. Given that the micros() function output is always multiples of 4, we’ll select a time delay of 100\u00b5s so it doesn’t affect the results we’ll be getting.<\/p>\n\n\n\n

    Here is the code example for this test.<\/p>\n\n\n\n

    \/*\n * LAB Name: Arduino delayMicroseconds Accuracy Test1\n * Author: Khaled Magdy\n * For More Info Visit: www.DeepBlueMbedded.com\n*\/\n\nunsigned long T1, T2;\n\nvoid setup()\n{\n  Serial.begin(9600);\n}\n\nvoid loop()\n{\n  T1 = micros();\n  delayMicroseconds(100);\n  T2 = micros();\n  Serial.println(T2-T1);\n  delay(1000);\n}<\/pre>\n\n\n\n

    <\/p>\n\n\n\n

    And here is the result for running this code on my Arduino UNO board.<\/p>\n\n\n\n

    \"Arduino<\/figure>\n\n\n\n

    <\/p>\n\n\n\n

    Do you remember from the previous example the sporadic fluctuation in the generated time delay? Here it’s also visible again. And we’ll eliminate it with the exact same way of creating a critical section for the delayMicroseconds function call (by disabling\/enabling Interrupts).<\/p>\n\n\n\n

    And here is the modified test code example.<\/p>\n\n\n\n

    \/*\n * LAB Name: Arduino delayMicroseconds Accuracy Test1\n * Author: Khaled Magdy\n * For More Info Visit: www.DeepBlueMbedded.com\n*\/\n\nunsigned long T1, T2;\n\nvoid setup()\n{\n  Serial.begin(9600);\n}\n\nvoid loop()\n{\n  noInterrupts(); \/\/ Disable Interrupts\n  T1 = micros();\n  delayMicroseconds(100);\n  T2 = micros();\n  interrupts();  \/\/ Re-Enable Interrupts\n  Serial.println(T2-T1);\n  delay(1000);\n}<\/pre>\n\n\n\n

    <\/p>\n\n\n\n

    And here is the result for running the modified test code example above. It’s a little bit better but still, there is a consistent random 4\u00b5s error. Which will stay the same whether you increase or decrease the delayMicroseconds time period. I went up to a 600\u00b5s time delay and it was printing 600s and 604s as well. So it’s something consistent and I believe it’s inherent in the micros()<\/code> function implementation itself.<\/p>\n\n\n\n

    \"Arduino<\/figure>\n\n\n\n

    <\/p>\n\n\n

    delayMicroseconds Accuracy Measurement Test2<\/h3>\n\n\n

    In this test procedure, I’ll replace the micros()<\/code> function calls with direct pin access to eliminate the execution time effect of the digitalWrite()<\/code> function and also avoid any effect introduced by the implementation of the micros function itself.<\/p>\n\n\n\n

    And I’ll run the test code on both the simulation environment and a real Arduino board with an oscilloscope to check if things are going to align or not.<\/p>\n\n\n\n

    Here is the code example for this test procedure. Note that I’m using PORTD<\/code> bit 3 which corresponds to Arduino digital IO pin number 3.<\/p>\n\n\n\n

    \/*\n * LAB Name: Arduino delayMicroseconds Accuracy Test2\n * Author: Khaled Magdy\n * For More Info Visit: www.DeepBlueMbedded.com\n*\/\n\nvoid setup()\n{\n  DDRD = DDRD | 0x08;\n}\n\nvoid loop()\n{\n  noInterrupts(); \/\/ Disable Interrupts\n  PORTD |= (1 << 3);\n  delayMicroseconds(100);\n  PORTD &= ~(1 << 3);\n  interrupts();  \/\/ Re-Enable Interrupts\n  delay(100);\n}<\/pre>\n\n\n\n

    <\/p>\n\n\n\n

    And here is the result of running this test code in both simulation and on a real Arduino UNO board.<\/p>\n\n\n\n\n\n\n
    Real Arduino + DSO Result<\/strong><\/td>\nProteus Simulation Result<\/strong><\/td>\n<\/tr>\n
    \"Arduino<\/td>\n\"Arduino<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n\n\n

    Which is quite an interesting result. Both pulses are very similar 98.6\u00b5s and 98.5\u00b5s. And also less than the expected 100\u00b5s pulse width.<\/p>\n\n\n\n

    Then, I proceeded with changing the delayMicroseconds input time delay down to 1\u00b5s. And here are the results I’ve got on my DSO after measuring the pulse width in each test case.<\/p>\n\n\n\n

    Test Case<\/strong><\/td>Measured Pulse Width on DSO<\/strong><\/td><\/tr>
    delayMicroseconds(100);<\/code><\/td>98.6\u00b5s<\/td><\/tr>
    delayMicroseconds(10);<\/code><\/td>9\u00b5s<\/td><\/tr>
    delayMicroseconds(2);<\/code><\/td>0.9\u00b5s<\/td><\/tr>
    delayMicroseconds(1);<\/code><\/td>0.2\u00b5s<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n

    To conclude this accuracy testing section, we can say that the Arduino delayMicroseconds function is pretty much accurate for general-purpose delay applications. However, there still are some fundamental limitations to what you can expect from this function and you’d be better off implementing your own delay routine if you need to have an extremely accurate and predictable behavior in your target application.<\/p>\n\n\n\n

    Otherwise, the delayMicroseconds will serve you well in most applications where a delay of a few \u00b5s is required and nobody is really concerned about the accuracy (or consistency) of the generated delay intervals.<\/p>\n\n\n\n


    \n\n\n
    \n\n

    Parts List<\/strong><\/p>\n\n\n\n

    Here is the full components list for all parts that you’d need in order to perform the practical LABs mentioned here in this article and for the whole Arduino Programming series of tutorials found here on DeepBlueMbedded. Please, note that those are affiliate links and we’ll receive a small commission on your purchase at no additional cost to you, and it’d definitely support our work.<\/p>\n\n\n

    \n\nArduino Course Kit List<\/a>\n\n<\/div>\n<\/div><\/div>\n\n\n

    This is the main DSO that I usually use in my lab in case you need one for your lab. You definitely need to check it out!<\/p>\n\n\n\n

    \"\"<\/figure>\n\n\n\n

    Amazon.com<\/a>   – ebay.com<\/a> – AliExpress<\/a><\/p>\n\n\n

    \n

    Download Attachments<\/strong><\/p>\n\n\n

    You can download all attachment files for this Article\/Tutorial (project files, schematics, code, etc..) using the link below. Please consider supporting my work through the various support options listed in the link down below. Every small donation helps to keep this website up and running and ultimately supports our community.<\/p>\n\n\n

    \n
    \n
    \n\nDOWNLOAD<\/a>\n\n<\/div>\n<\/div><\/div><\/div>\n\n
    \n
    \n\nDONATE HERE<\/a>\n\n<\/div>\n<\/div><\/div><\/div>\n<\/div>\n\n\n
    \n\n<\/div><\/div>\n\n

    Concluding Remarks<\/strong><\/h2>\n\n\n

    To conclude this tutorial, we can say that the Arduino delayMicroseconds function is pretty much accurate for general-purpose delay applications. However, there still are some fundamental limitations to what you can expect from this function and you’d be better off implementing your own delay routine if you need to have an extremely accurate and predictable behavior in your target application.<\/p>\n\n\n\n

    Using the delay() and delayMicroseconds() functions is pretty much easy. But you need to be very careful and use them reasonably because it can lead to major timing issues in your system. And in most cases, you’d be better off avoiding using delays altogether.<\/p>\n\n\n\n

    In the following cases, it’d be acceptable to use delays in your Arduino projects:<\/p>\n\n\n\n