In an earlier article I wrote, I tested how fast I could push the HiTechnic ProtoBoard and the MAX127 ADC under ROBOTC. In a recent discussion with Deepak from Mindsensors, I2C speeds in ROBOTC on the NXT came up. The questions arose about the most efficient read size for the NXT and if there was a ceiling or a cut-off point.
So, rather than taking a guess, I wrote a quick ROBOTC program to test the time taken to repeatedly do requests for an ever increasing number of bytes. The program would do a 1000 reads of 1 byte, time the results, then repeat the same 1000 requests for 2 bytes, all the way up to 16 bytes. The results were quite interesting and not nearly as linear as you’d expect. I made use of the new I2C calls “clearI2CStatistics()” and “getI2CDriverStatistics()”. They allow you to gather information on internal I2C statistics, such as failed pull-up tests, number of retransmits and other things. You can find more information about them in the "I2CIntrinsics.h" header file included with the latest release of ROBOTC (2.00 preview at the time of writing this article).
So without further ado, here are the results:
Read size (B) | Time Taken (ms) | Bytes/s | Transaction time (ms) | Transaction/s |
1 | 1995 | 501 | 2.00 | 501 |
2 | 2000 | 1000 | 2.00 | 500 |
3 | 2000 | 1500 | 2.00 | 500 |
4 | 2994 | 1336 | 2.99 | 334 |
5 | 3000 | 1667 | 3.00 | 333 |
6 | 3000 | 2000 | 3.00 | 333 |
7 | 3989 | 1755 | 3.99 | 251 |
8 | 4000 | 2000 | 4.00 | 250 |
9 | 4000 | 2250 | 4.00 | 250 |
10 | 4549 | 2198 | 4.55 | 220 |
11 | 5000 | 2200 | 5.00 | 200 |
12 | 5000 | 2400 | 5.00 | 200 |
13 | 5347 | 2431 | 5.35 | 187 |
14 | 6000 | 2333 | 6.00 | 167 |
15 | 6000 | 2500 | 6.00 | 167 |
16 | 6011 | 2662 | 6.01 | 166 |
Number of bytes read per second. | Average time per I2C transaction. This includes the time required to send the request and for the reply to be received and read. | Number of transactions per second. |
So what conclusions can we draw from this? If it’s sheer bandwidth you need then reading 16 bytes at a time is the way to go. However, it does reduce the number of total transactions per second to about 166. If you need to poll a sensor very frequently, it is paramount to keep the number of bytes requested down.
Tests were done using two sensors, a Mindsensors Accel-NX and the HiTechnic Colour Sensor (V1). The results were identical (with a deviation of perhaps 4-6 ms). The sensor was configured as a custom I2C sensor using the fastest possible clock speed. Please note that a lot of sensors are not guaranteed to work flawlessly at these speeds. However, neither sensor produced any errors during the test runs. ROBOTC version 2.00 preview was used, the program was compiled with the “release” setting and without a connection to the debugger. Runs with the debugger connected and with the “debug” setting enabled showed no difference in performance.
Remember, there are three kinds of lies: lies, damned lies, and statistics.. Use the above data with caution!
You can download the source for the program here: [LINK].