2013/12/31
Intel Galileo ポート操作が異様に遅い
液晶ディスプレイへの書き込みが気が遠くなるほど遅く、使い物にならないので調べてみました。
最初にポート操作(digitalWrite)の処理速度を確認するために、下記のスケッチでポート操作に必要な時間を計測してみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
int led = 13; void setup() { Serial.begin(9600); Serial.println("Start"); pinMode(led, OUTPUT); } void loop() { long tt = millis(); for (int i = 0; i <1000; i++) { digitalWrite(led, HIGH); digitalWrite(led, LOW); } tt = millis() - tt; Serial.println(tt); while(1); } |
Arduino UNO(IDE:1.0.5)では、10,000回ループで82msでしたが、Galileo(IDE:1.5.3)では、1,000回で4,778msでした(Galileoでは、10,000回でなく、1,000回ループ)。
UNOが約4usで処理されているところを約2ms以上を要しています、約500倍遅いということになります。
次にポート設定(pinMode)の処理速度が気になったので、ポート設定をループ内部に移動して計測しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
int led = 13; void setup() { Serial.begin(9600); Serial.println("Start"); } void loop() { long tt = millis(); for (int i = 0; i <1000; i++) { pinMode(led, OUTPUT); digitalWrite(led, HIGH); digitalWrite(led, LOW); } tt = millis() - tt; Serial.println(tt); while(1); } |
結果、Arduino UNOでは、10,000回ループで128msでしたが、Galileoでは、1,000回で23,840msでした(Galileoでは、10,000回でなく、1,000回ループ)。
Galileoでは、ポート設定に約10msを要しています。
普通に考えるとポート設定は、初期化の時に1回だけ実行するものと思いますが、実はこのポート設定処理が液晶ライブラリのポート出力を行うときに毎回呼び出されていました。
これが、液晶表示を異様に遅くしている原因のようです。
1 2 3 4 5 6 7 8 |
void LiquidCrystal::write4bits(uint8_t value) { for (int i = 0; i < 4; i++) { pinMode(_data_pins[i], OUTPUT); digitalWrite(_data_pins[i], (value >> i) & 0x01); } pulseEnable(); } |
このポート設定をLiquidCrystal::init()に移動して、初期化時に1回だけ設定するように変更すると多少速くなります。
それでも、実用に耐える速度ではありません(-_-;)
1 2 3 4 5 6 7 8 9 |
if (fourbitmode) { _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; for (int i = 0; i < 4; i++) pinMode(_data_pins[i], OUTPUT); } else { _displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS; for (int i = 0; i < 8; i++) pinMode(_data_pins[i], OUTPUT); } |
コメント:0