今やっている実験の一環でこんなコードを走らせています:
if (digitalRead(pinDeviceReadReady) == HIGH) { Serial.println("DATA READY"); spiSend(0x20); // command "read request" readBuffer.deviceId = spiReceive(); Serial.println(readBuffer.deviceId); readBuffer.wireId = spiReceive(); Serial.println(readBuffer.wireId); readBuffer.length = spiReceive(); Serial.println(readBuffer.length); for (int i = 0; i <= readBuffer.length; ++i) { readBuffer.data[i] = spiReceive(); Serial.println(readBuffer.data[i]); } } where inline void spiSend(uint8_t data) { // wait for device ready to write while (digitalRead(pinDeviceWriteReady) == LOW); SPI.transfer(data); } inline uint8_t spiReceive() { while (digitalRead(pinDeviceReadReady) == LOW); uint8_t data = SPI.transfer(0); return data; }
実際の動作パタンは以下のようになりました。赤線は DATA READY をあらわすインジケータの出力で、青線はそれを受けて起動される SPI 転送クロックです。見てわかるように、かなり大きな遅延が出ています。
遅延は、デバッグのためにSPI転送の間に挿入されている Serial.println() が原因のようです。Serial.println() の実装は見ていませんが、どうもこの行の実施には 100μS から 150μS ぐらいの所要時間がかかるようです。
Serial.println() 行を取り除くと、大きな遅延は見られなくなりました。
でも波形を拡大してみるとまだ遅延があるようです。
これはおそらく DATA READY インジケータを読むための digialRead() による遅延か SPI.transfer() の実施に遅れがあるためと思われます。この実験では今すぐ除去する必要はないのですが、3μS ほどの遅延があることは頭に入れておいたほうがよさそうです。