chipKit系でもう一つ気になるのが、USB-RS232C周り。Arduinoの場合、ポートOpen直後には2秒ほど反応がない、という問題がある。一度Openすると、その後はCloseするまでは非常に反応は高速なのだが、煩雑にOpen/Closeを繰り返すようなケースでは、毎回2秒程度の待ちが必要になる。

ということで、まずList 1の様なスケッチを実行してみる。これは何か? というと、シリアルポートから受け取ったデータを鸚鵡返しに送り返すというものである。やってみると、少量のデータであればすぐさま受け取ることができるし(Photo01)、ちょっと量が多くなってもバッファにたまるのはせいぜい5Bytes程度(Photo02)で処理できている。これに関しては、Arduino UnoとchipKit Uno32で全く振る舞いは同じだった。また、このスケッチを起動すると、最初2秒ほどはシリアルコンソールの入力に反応しない。これもまたArduino UnoとchipKit Uno32では全く同じであった。このあたりが多少改善されていると、もう少しPCとArduinoのデータ通信が楽になるのだが、とりあえずほぼ振る舞いが同じ、という事が判っただけでもよしとしたいと思う。

Photo01: "123"を入力すると、毎回改行される。これはfor()ループの中の「Serial.print(Serial.read(), BYTE);」の処理が十分早いので、9600bpsだと1文字受け取ってから次の1文字を受け取る前に処理が終わるという話。

Photo02: 文字列を長くすると、送信と受信が同時に行われる関係でキューが間に合わなくなるのか、最大5バイトほどバッファに蓄えられ、まとめて処理される形に。

余談になるが、この原稿ではArduino IDEを0022 αを使っている。これはなぜかというと、chipKit向けのMulti Platform Version Arduino IDEがやはり0022 αをベースにしたものしかまだリリースされていないので、互換性を考えての話であるが、本家Arduinoの方はというと、公式ダウンロードページはまだ0022 αのままながら、今年9月17日にArduino 1.0のアナウンスがなされている。これはハードウェアとソフトウェアを完全に固定するというもので、これが実現すると1.0ベースで作ったハードウェアとかスケッチを長く(例えば最終製品などに搭載する形で)利用するのも現実的になるだろう。10月4日には1.0 RCのArduino IDEもリリースされており、今年中には完成版の1.0がリリースされるかもしれない。

この1.0では複数のSerialポートを正式にサポートするほか、送信のNon Blocking化の実現とかSerial.flush()の若干の挙動の変化(現在のSerial.flush()は受信側データについてのみ説明があり、送信側は不定(実際には送信前データも破棄される)だったのだが、今度から送信前データは留保されることになった。またSerial.print(x,BYTE)の振る舞いが変わり、例えば以前なら、

Serial.print(78, BYTE);

とすると"N"が送られていたのが、今度から"78"という文字が送られるように変更された。他にもいくつかSerialまわりの変更があり、最終的にはSerial Libraryそのものが再実装されたようだ(というか、再実装するのにあわせてこうした変更が数多く行われたというか)。

恐らくは1.0-stableが登場した後でchipKitの方もこれを取り込む形でアップデートを行うのではないかと思うが、今のところ明確なアナウンスはない。実のところchipKit IDEの方も結構色々とバグが多いようで、Software Builds and Announcementsを覗くと、結構多いバグフィックスを行ったTest Buildがちょくちょくリリースされており(現時点での最新版は20110907版)、先にこうしたバグフィックスが一段落してからAndroid 1.0ベースにポーティングとなるかもしれない。

ということで、数回にわたってchipKitをご紹介した。これはこれでアリ、という気はするので、次のネタはArduinoとchipKitの両方で動くようなものにしようかと思っている。

List1:

#define  BUFSIZ  256

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  int lpCnt;    
  for (lpCnt=0; lpCnt < Serial.available(); lpCnt++)
  {
    Serial.print(Serial.read(), BYTE);
  }
  if (lpCnt != 0)
    Serial.println();
}