Tweet昨日試したサンプルプログラムのソフトウェアシリアル通信対応版の作成に挑戦している。Arduinoでソフトウェアシリアル通信を行うためには、Arduino標準ライブラリのSoftwareSerialを使うと良いと思われる。この標準ライブラリ、かつては機能制限が多くNewSoftSerialというものが代替としてよく利用されていたようだ。1.0になってそのNewSoftSerialライブラリが本家のSoftwareSerialに置き換わった。1.0からのSoftwareSerialと同等であるとみなして問題ない(多分)。ソースコードの改造はほぼ機械的で、ハードウェアシリアル通信を表すSerialを、ソフトウェアシリアル通信のものに置き換えるだけだ。修正にあたっては「なんでも作っちゃう、かも。JPEGカメラモジュールで写真を撮る」を参考にした。RCS620S.h、そして付属するサンプルスケッチFeliCaPush.inoである(つまり全部)。次にコードの修正部分を示す。{}}問題解決に当たり、せっかくなので、ソフトウェアシリアルポート(今回は2ピン、3ピン)から送受信されているデータをPCにハードウェアシリアル送信してみた。それをシリアルモニタで観察した図を次に示す。RC-S620/S間のジャンパ線を引っこ抜くと、受信文字列が出ないことが確認できた。このことからちゃんとソフトウェア送信ポート(3ピン)からデータをシリアル送信して、受信ポート(2ピン)で受信することはできていると思われる。問題はその受信データである。ACKフレームを示すバイト列「00-00-FF-00-FF-00」が返って来なければならないのに、実際には上図に示すように「00-80-00-FF-80-00」が返ってきている。この結果は何回やっても変わらず、それが私の頭を悩ませている。解決に向けて同様のロジックで、かつハードウェアのシリアル通信機能を利用している時は問題なく動くことから、ロジックは正しいと考えられる。実は、前出のソースコード中でさりげなく使っているSoftwareSerial::flush()関数は、Arduino標準リファレンスのドキュメントに載っていない。実装としてはあるために一応使うことはできる。フォーラムでの議論を流し読みした感じ、そもそもハードウェア版シリアルポートであるSerial.flush()の実装ですら途中で仕様が変わっているようなことが書いてある。「なんでも作っちゃう、かも。リリース」によると、Serial送信の非同期化と題して以下の記述が見える。Serial.print()などデータの送信はバックグラウンドで行われるようになりました。Serial.flush()は受信データを破棄する処理から、送信データがすべて送信されるまで待つ処理に変更されました。ハードウェアシリアル通信のflush関数(送信データがすべて送信されるまで待つ処理)で上手く行っている以上、ソフトウェアシリアル通信のflush関数でも同等の処理をするように変更する必要があると思われる。......これはなかなかに骨が折れそうである。