Arduino UNO での Serial.println() にかかる時間

今やっている実験の一環でこんなコードを走らせています:

   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 転送クロックです。見てわかるように、かなり大きな遅延が出ています。

data_ready_and_SPI_clock_with_serial

遅延は、デバッグのためにSPI転送の間に挿入されている Serial.println() が原因のようです。Serial.println() の実装は見ていませんが、どうもこの行の実施には 100μS から 150μS  ぐらいの所要時間がかかるようです。

Serial.println() 行を取り除くと、大きな遅延は見られなくなりました。

data_ready_and_SPI_clock_without_serial

でも波形を拡大してみるとまだ遅延があるようです。

data_ready_and_SPI_clock_closeup

これはおそらく DATA READY インジケータを読むための digialRead() による遅延か SPI.transfer() の実施に遅れがあるためと思われます。この実験では今すぐ除去する必要はないのですが、3μS ほどの遅延があることは頭に入れておいたほうがよさそうです。

Comments

No comments yet. Why don’t you start the discussion?

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

This site uses Akismet to reduce spam. Learn how your comment data is processed.