GalileoのI/O関連でうまく動作しないトラブルが発生。
その直接の原因ではないが、調べていて通常のArduinoとは違う注意すべき点があることに気付いた。
I/Oの初期設定のタイミングだ。
例えば他のBlogとかで、LiquidCrystalライブラリを使ったスケッチがそのままでは動作しない、という記事がある。
例えばこんなかんじ。
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup() {
lcd.init(1, 12, 255, 11, 5, 4, 3, 2, 0, 0, 0, 0);
(以下略)
このようにsetup()の中でLiquidCrystalクラスのinitを呼ばなければならない。
この原因は使用するライブラリのクラスのコンストラクタと、main()関数にあるようだ。
Galileoのmain関数の中ではinit関数が呼ばれ、その中でpinInit関数が呼ばれる。
GalileoのI/O端子はI/Oエキスパンダの後にマルチプレクサのICが接続されている。例えばpinMode関数を呼べば、I/O関連の設定とともにマルチプレクサが切り替えられるようだ。しかしpinInit関数が呼ばれていないとマルチプレクサが正しく切り替わらないようだ(詳細未確認)。
そして、例えば上記LiquidCrystalのようにグローバルなインスタンスを置いた場合、そのインスタンスの初期化はmain関数の実行前に行われる。つまりそのクラスのコンストラクタはmain関数の前、pinInit関数の実行前に実行されることになる。よって、コンストラクタ関数内に例えばpinMode()関数がある場合はそれが正常に動作しないのかもしれない。
残念ながら、main関数に入った後にグローバルに置かれたインスタンスのコンストラクタを実行させる事は基本的には不可能。LiquidCrystalクラスはコンストラクタの中からinit関数を呼び、init関数内でpinMode等を実行しているので、setup()の中(つまりmain()の中)でもう一度initを実行することで正しく設定できるようになっているようだ。
という事で、もし他のスケッチ等のライブラリでもコンストラクタ内で直接pinMode等を実行しているようなものであれば厄介。コンストラクタは各種パラメーターの保存にとどめ、I/O関連の設定は別の(publicな)メソッドで実行するようにライブラリを書き換えたほうがいいだろう。
スポンサーサイト