作品タイトル:GR-KURUMIの機能を使う シリアル編
表示名:@chobichan
コンセプト・作品説明 |
---|
GR-KURUMIのシリアル機能を使います |
シリアルを使ってみる
例によってWEBコンパイラにログインし、新しいプロジェクトを生成しても構いませんし、前回のビルドしただけのプロジェクトを開き直すのでも構いません。ちょっと実験してみましょう。Arduinoと言いますかCPUであるAtmega328Pと異なりGR-KURUMIのCPUのRL78/G13は複数のハードウエアシリアルを持っています。そのうちGR-KURUMIでサポートされているのは、Serial、Serial1、Serial2の3つになります。
それぞれ使い方は以下の様なコードを記述すれば大丈夫です。
void setup() { Serial.begin(9600); Serial.println("hello serial."); Serial1.begin(9600); Serial1.println("hello serial1."); Serial2.begin(9600); Serial2.println("hello serial2."); }
Serialが利用するGR-KURUMIの端子番号0、1は書き込みに使用するRXI、TXOと兼用です。この為、 GR-KURUMIにプログラムを書き込み後、そのままの状態でTera Termで出力を見ることができました。
Serial1が利用する端子は7番、8番となります。
Serial2が利用する端子は9番、10番となります。
Serial1、 Serial2共にUSBシリアル変換チップ等に接続されていませんので、もしこのSerial1、 Serial2の出力をPC等で見たいとするならば、ユーザーが何らかのデバイスとのハードウエア上の接続を行う必要が有ります。よく使うのはXBee等の無線モジュールでしょうか。
通信速度
Arduino Pro MiniはCPUクロックが8MHzで動いています。試してみたところArduino Pro Miniの通信速度(baud rate:単位はbps)は57600bps辺りが限度です。
GR-KURUMIのCPUは32MHzで動いています。この為Arduino Pro Miniよりは速い速度で通信ができるようです。GR-KURUMI用に以下のコードを用意してみました。
void setup() { Serial.begin(230400); while(1) { while( Serial.available() == 0 ) ; Serial.write(Serial.read()); } }
プログラムは、受信したら送り返し、受信したら送り返し、を繰り返しているだけです。
この様なプログラムを折り返し(ループバック)プログラムと言い、基板やケーブル等のハードウエアの正常/異常を簡易的に調べるのに役立ちます。
GR-KURUMI はArduino Pro Miniより速い通信速度が設定できますが、大量のデータを送受信する時にフロー制御等を行わない無手順の場合、データの欠落が時折発生します。
どちらに問題があるのか一概に言えませんが、通信を行う上でこの欠落が発生し得る事を考慮する必要がありますね。※フロー制御にはハードウエアで行うものとソフトウエアで行うものが有ります。いずれも受信バッファの状況が判らないと実現できないので、フロー制御をライブラリ側でサポートしてくれているとイイのですが。
手をつないで輪になって
折角3つのシリアルが有るのですから、ちょっと変わった動作確認を行ってみます。以下のコードを参照してください。ブレッドボード上の配線は図の様になります。7番と8番、9番と10番をジャンプワイヤー等で接続します。
void setup() { Serial.begin(115200); Serial1.begin(115200); Serial2.begin(115200); while(1) { if( Serial.available() > 0 ) Serial1.write(Serial.read()); if( Serial1.available() > 0 ) Serial2.write(Serial1.read()); if( Serial2.available() > 0 ) Serial.write(Serial2.read()); } }
Serialから受信したデータはSerial1に送信されます。
それが戻ってきてSerial1で受信されますので、今度はそのデータをSerial2に送信します。
そのデータも戻ってきてSerial2で受信されます。
最後は受信データをSerialに送信して、3つのシリアルを経由して折り返しが行われます。
バッファサイズの調整
シリアルで通信を行うとき、データをパケット化して扱う事がしばしば発生します。数十から数百byteのパケットを送受信する時、シリアルのバッファに十分な大きさが有れば一回で取り込み、書き込みが出来てしまいプログラムの効率が良くなります。これがArduino Pro Miniであればバッファに使用するSRAMのサイズ自体が2Kbyteと小さく、そうも行かないのですが、これはGR-KURUMIです。10倍のSRAMを積んでいます。
ところがですね、ライブラリはArduinoに合わせて64byteのバッファサイズしか有りません。10倍もRAM容量が有るのにですよ。GR-KURUMIのシリアルはインスタンス生成時に自動的にバッファ等を生成するのではく、静的に、つまり起動時点ですでに確保されています。
このサイズを決めているソースコードは「HardwareSerial.cpp」に記述されています。
定義SERIAL_BUFFER_SIZEの数字を増やしたり減らしたりすれば、送受信に使用しているバッファのサイズが調整できます、、、
納得行かないですね。
定義SERIAL_BUFFER_SIZEの数字を変更すると、送信も受信も、SerialもSerial1もSerial2もサイズ変更になってしまいます。
全部は使わないかもしれないのに。構造体ring_bufferは、バッファのアドレスとサイズと、それにheadとtailで構成してくれれば、別に生成したバッファとそのサイズを代入する事でこの問題を解消できたのですが。こんな感じで。
struct ring_buffer { unsigned char *buffer; volatile unsigned int head; volatile unsigned int tail; volatile unsigned int size; };
https://dl.dropboxusercontent.com/u/60463387/grkurumi/hardwearSerial/HardwareSerial.cpp
極一般のハードウエアエンジニア。たまに雑誌記事を書いています。
twitterアカウント:https://twitter.com/chobichan