目次
前
次
ArduinoMega2560マルチ通信
ArduinoMega2560は、シリアルインタフェースを
0から3の4チャネル持ちます。
チャネル0とチャネル1のデータ転送速度が異なる
システムが必要となったので、次の仕様でUSB接続
されているチャネル0で、チャネル1と外部装置の
データ交換を試験してみます。
システム構成を見ると、次のようになります。
チャネル0がチャネル1の動作をモニタするので
チャネル0を、デバッキングエイドにした。
パーソナルコンピュータとチャネル0のインタフェースは
データ交換するための受信割込みは、次のように定義して
おきます。
void serialEvent()
{
byte ch;
if ( Serial.available() > 0 ) {
/* get 1 character */
ch = Serial.read();
/* store */
*(sbuf+sindex) = ch ;
/* increment */
sindex++ ;
/* judge */
if ( ch == '\r' ) {
sindex = 0 ;
uflag = ON ;
}
}
}
USB/シリアルのチップを使うので、9600bps程度では
パーソナルコンピュータからの1文字コマンドを受信
バッファに格納するだけで充分。
受信バッファは、次のように配列で確保すれば充分。
char sbuf[16] ;
byte sindex ;
配列の中に情報格納するためのインデクスポインタに
sindexを使います。
コマンドとパラメータで構成したフレームの最後は
'\r'として、検出したなら対応ブロックが動作できる
ように、通知フラグにて、お知らせ。
通知フラグでトリガーがかかると、次のように
対応した処理を実行します。
if ( uflag ) {
/* clear flag */
uflag = OFF ;
/* execute command interpreter */
execdebug();
}
チャネル1では、データ転送速度が高速なので
取りこぼさないよう、リングバッファを採用。
リングバッファを扱う関数は、以下。
char sbrbuf[128] ;
byte sbrdp ;
byte sbwdp ;
byte sbcap ;
void init_sbring()
{
byte ii ;
/* clear */
for ( ii = 0 ; ii < 16 ; ii++ ) {
*(sbrbuf+ii) = '\0' ;
}
sbrdp = 0 ;
sbwdp = 0 ;
sbcap = 0 ;
}
void put_sbring(char x)
{
/* store */
*(sbrbuf+sbwdp) = x ;
/* update pointer */
sbwdp++ ;
sbwdp &= 0x7f ;
/* update capacitor */
sbcap++;
}
char get_sbring()
{
char result ;
/* get */
result = *(sbrbuf+sbrdp) ;
/* update pointer */
sbrdp++ ;
sbrdp &= 0x7f ;
/* update capacitor */
sbcap--;
return result ;
}
byte get_sbring_size()
{
return sbcap ;
}
void show_sbring()
{
byte ii ;
/* show */
for ( ii = 0 ; ii < 128 ; ii++ ) {
/* show 1 character */
rs_putchar( *(sbrbuf+ii) );
/* new line */
if ( (ii % 16) == 15 ) crlf();
}
}
128バイトの配列を用意し、リード、ライトのポインタに
使っている容量を計算しています。
リングバッファを使うと、受信割込みハンドラは
次のように記述できます。
void serialEvent1()
{
byte ch ;
byte sbn ;
byte ii ;
/* get code */
sbn = Serial1.available() ;
if ( sbn > 0 ) {
for ( ii = 0 ; ii < sbn ; ii++ ) {
/* get 1 character */
ch = Serial1.read();
/* store */
put_sbring( ch );
/* judge */
if ( ch == 0x0a ) { sbuflag = ON ; }
}
}
}
Serial1クラスでは、内部に64バイト程度の
バッファを用意しているので、受信文字数を
取得し、リングバッファに格納しておきます。
データフレームは、ラインフィードで終了するとして
1フレームがリングバッファに格納されたなら、通知
フラグで、処理ブロックにトリガーを出力。
通知フラグを貰ったブロックは、次のように必要な
仕事を、下位へと渡します。
if ( sbuflag ) {
/* clear flag */
sbuflag = OFF ;
/* execute command interpreter */
sbexec();
}
2台のArduinoMega2560は、次のようにブレッドボード経由で
TxD、RxD、GNDを接続して実験しました。
素麺の木箱にビスを立てて、ArduinoMega2560を挿し
ブレッドボードのワイヤーで、クロス接続状態にし
通信環境を整えています。
それぞれのArduinoMega2560とは端末ソフトTeraTermで
PC上からの操作ができるようにておきます。
次のように2つの端末画面で、データ交換を確認。
左と右で、役割を分担しています。
左でパラメータを伴うコマンドを入力すると、右には
送信文字を表示。表示と同時に、該当情報を返信。
左の端末は、受信データを表示。
PCとArduinoMega2560の間は、9600bpsでデータ交換しますが
ArduinoMega2560の間は、115200bpsと高速で通信しています。
この形態を使うと、Arduinoを他のマイコン基板用の
デバッガに変身させることも可能になります。
目次
前
次