I researched several options for this, including high speed serial, SPI, I2C, and direct USB communications. Simply increasing the speed on a standard serial connection for the Arbotix did not work. It is just too error prone at high speeds for a reliable data transfer. Apparently the Due can reach a max of around 850 Kbyte/s, but SPI on the Jetson is faster, with a maximum clock speed of 25 MHz. Also, raw serial will always be more error prone than SPI because it lacks the dedicated clock that SPI has. This is used to lock in the bit value on the falling or rising edge of the clock, making it much more robust. So I decided not to continue pursuing raw serial communications since SPI was better.
I2C faces a similar problem as raw serial. It does have a dedicated clock signal, but because of the nature of the open drain connections, and the complicated algorithms used for this protocol, it is not really suited for high speed applications. The capacitance of the wire and components in the open-drain configuration causes the signals to rise and fall slowly. I2C typically works at 400 Kbit/s. It does have a high speed mode for 3.4 Mbit, and an ultra high speed mode for 5 Mbit. However, very few devices support these modes, so it is difficult to use them in practice, and again, this was slower than is possible with SPI. So I2C was also ruled out.
Direct USB is a possible answer, but it is not without its own problems. For most Arduinos it is not really an option. Their clock is simply too slow to reach the high speeds needed to come close to attaining USB transfer speeds. USB 2.0 can theoretically reach a maximum speed of 480 Mbits per second (mbps) in high speed mode. However, this is the raw bus speed, and in practice it is usually much less than this (see this link for reference). This would be way more than enough, if you could get it to work. However, you only got those phenomenal speeds when you are sending large chunks of data (64 Kbyte packets). The USB protocol is not setup to deal well with numerous small chunks of data. So your data transfer rate goes way, way down. There is also latency issues due to the polling interval of the USB protocol that limits the transfer rate. Based on some of the published numbers I was seeing for using the native USB serial port of the DUE, it would still be slightly slower than what I could attain using SPI. The newer USB 3.0 can theoretically reach 5 gbps. Even with the slow down caused by sending a bunch of smaller packets it would probably be more than fast enough to get the kind of transfer rate I need. Unfortunately, to my knowledge there is no Arduino that yet implements a USB 3.0 controller that can be used for this type of communications. So while it may be possible to get direct USB 3.0 transfer working in the future, for now it was off the table for me. I do plan to go back at some point and do some experiments with the Due on my own to see what kind of data transfer rate I can get using this method.
This left the SPI protocol as the winner. On the Jetson TK1 it has a maximum clock frequency of 25 MHz. However, using full-duplex mode you can simultaneously send and receive data. So the overall data transfer rate is 50 mbps. This should more than meet my needs for transferring sensory and motor data at 100 Hz, or possibly even higher. Also, since SPI has a dedicated clock signal it is much less error prone than raw serial communication. Therefore, SPI was the clear winner, all that was left to do was figure out how to get it to work. So with that being said, let's dive into this and I will show you how to get it to work on the Jetson TK1 and Arduino Due. In the next part of the series I will show you how to configure the Jetson and enable the SPI devices in the kernel.
Please subscribe to my Newsletter!
NeuroRobotic Technologies is dedicated to creating the next generation of intelligent, adaptive robotic systems by building autonomous controls systems that mimic the brains of real animals.