液晶ディスプレイへの書き込みが気が遠くなるほど遅く、使い物にならないので調べてみました。
最初にポート操作(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回だけ実行するものと思いますが、実はこのポート設定処理が液晶ライブラリのポート出力を行うときに毎回呼び出されていました。
これが、液晶表示を異様に遅くしている原因のようです。
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回だけ設定するように変更すると多少速くなります。
それでも、実用に耐える速度ではありません(-_-;)
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 ) ;
}