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
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 <\/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\nHere 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\nArduino delayMicroseconds Accuracy Tests<\/strong><\/h2>\n\n\nIn 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 <\/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 <\/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\nAnd 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\nReal Arduino + DSO Result<\/strong><\/td>\nProteus Simulation Result<\/strong><\/td>\n<\/tr>\n\n <\/td>\n <\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n\n\nWhich 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\nTest 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\nTo 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