Arduinoで遊ぶページ

Arduinoで遊んだ結果を残すページです。
garretlab
性能測定実験(I/O)

概要

Arduino UnoのIOの性能測定を行いました。

目的

Arduino UnoのdigitalRead()、digitalWrite()、analogRead()の3つの関数の性能を、ピンごとに測定し、特性を調べます。

測定方法

各関数を10000回実行し、その前後でmicros()を使って時刻を取得しておき、測定後、1回あたりの各関数の実行時間を測定します。このため、ループを制御するための時間も含んでいます。

Arduinoには何も接続しない状態で、デジタルピンはdigitalRead()とdigitalWrite()の2種類、アナログピンはさらにanalogRead()の実行時間を取得しました。digitalRead()とanalogRead()の実行結果は、volatile宣言した変数に代入しました。analogRead()は、計測前にに1回実行した後、10000回実行しています。

実験結果

2回実行した結果を以下に示します。単位はマイクロ秒です。1回目と2回目とで値が異なったものはありませんでした。

ピン番号 digitalRead() digitalWrite() analogRead()
1回目 2回目 1回目 2回目 1回目 2回目
0 4.40 4.40 4.28 4.28 - -
1 4.40 4.40 4.28 4.28 - -
2 4.40 4.40 4.28 4.28 - -
3 5.22 5.22 5.16 5.16 - -
4 4.40 4.40 4.28 4.28 - -
5 5.22 5.22 5.16 5.16 - -
6 5.16 5.16 5.09 5.09 - -
7 4.40 4.40 4.28 4.28 - -
8 4.34 4.34 4.28 4.28 - -
9 5.09 5.09 4.97 4.97 - -
10 5.53 5.53 5.47 5.47 - -
11 5.22 5.22 5.16 5.16 - -
12 4.34 4.34 4.28 4.28 - -
13 4.34 4.34 4.28 4.28 - -
14(アナログ0) 4.34 4.34 4.28 4.28 112.01 112.00
15(アナログ1) 4.34 4.34 4.28 4.28 112.01 112.00
16(アナログ2) 4.34 4.34 4.28 4.28 112.01 112.00
17(アナログ3) 4.34 4.34 4.28 4.28 112.01 112.00
18(アナログ4) 4.34 4.34 4.28 4.28 112.01 112.00
19(アナログ5) 4.34 4.34 4.28 4.28 112.01 112.00

考察

(私の)Arduino Unoでは、digitalRead()は約4.34~5.53マイクロ秒、digitalWrite()は4.28マイクロ秒~5.47マイクロ秒、analogWrite()は約112マイクロ秒かかることがわかりました。ただし、ループ時間込なので実際にはもう少し短い時間で実行できていると思います。

ピンごとに見ると、3・5・6・9・10・11の6つのピンは他のピンと比べてデジタル入出力の性能が(わずかですが)悪いことがわかります。これらのピンは、PWM出力ができるピンと同じです。Arduinoのソースコードを見てみると、PWM出力可能なピンでは、PWM出力をOFFにするという操作を行っていました。このぶん他のピンに比べて余分に時間がかかっているようです。

ほんの少しでも性能を求めるアプリケーションであれば、PWM出力ができないピンを利用するのがいいと思われます。さらに性能を求める場合は、PORTレジスタを用いるのがいいと思います。簡単に試した結果、読み書きとも1マイクロ秒かからないで実行できました。

analogRead()のリファレンスには、約100マイクロ秒かかる("It takes about 100 microseconds (0.0001 s) to read an analog input")と書いてあり、ほぼそのような結果となりました。

スケッチ

今回の実験に使用したスケッチを以下に示します。

const int repeat = 10000;

void measure(int pin) {
  long begin, end;
  volatile int val;
  
  Serial.print("Pin No.: ");
  Serial.println(pin);

// digitalRead()
  pinMode(pin, INPUT);
  delay(1000);
  begin = micros();
  for(int i = 0; i < repeat; i++) {
    val = digitalRead(pin);
  }
  end = micros();
  
  Serial.print("  digitalRead:    ");
  Serial.println((end - begin) / (float)repeat);

// digitalWrite()
  pinMode(pin, OUTPUT);
  delay(1000);
  begin = micros();
  for(int i = 0; i < repeat; i++) {
    digitalWrite(pin, HIGH);
  }
  end = micros();
  
  Serial.print("  digitalWrite:   ");
  Serial.println((end - begin) / (float)repeat);
  
// analogRead()
  if ((pin >= A0) && (pin <= A5)) {
    val = analogRead(pin);
    begin = micros();
    for(int i = 0; i < repeat; i++) {
      val = analogRead(pin);
    }
    end = micros();
  
    Serial.print("  analogRead:   ");
    Serial.println((end - begin) / (float)repeat); 
  }
  
  Serial.println();
}
  
void setup () {
  int pin;
  
  Serial.begin(9600);
  
  for(pin = 0; pin < 20; pin++) {
    measure(pin);
  }
}

void loop () {
}

バージョン

Arduino 1.0



メニューを表示するためにJavaScriptを有効にしてください。

Arduinoで遊ぶページ
Copyright © 2011 garretlab all rights reserved.
inserted by FC2 system