H8-3069ネット対応マイコンにMESを入れる > 基本編9.H8-3069ボード同士の通信

9.H8-3069ボード同士の通信

タイミングが難しい

基本編7・8でシリアルポートsci0を使った送信・受信を行いました。その時は対パソコン(のハイパーターミナル)だったわけですが、この基本編9ではマイコン同士のsci0を使った通信を取り上げます。なお、扱うのは「文字列」です。一方のH8-3069LANボードからもう一方のH8-3069LANボードへsci0を使って「文字列」を送信します。それを受け取って、受けた方のボードの液晶に受け取った文字列を表示するプログラムです。
最初に申し上げますが、この「マイコン同士の通信」は難しいです。もちろん初心者だからそう思うのかもしれませんが、とにかくタイミングを計ってプログラムを書かないと送信した文字列を受け取ってくれません。
ちなみに、やまねこさまのサイトに「ハードウェアフロー制御」について載ってますが、初心者はなるべく現在の状況のままで通信できる方法をまずやってみたいと考えました。以下の方法はかなり原始的だと思いますが、とりあえず動いたので載せたいと思います。sleep()の時間をうまく調整してもっと取りこぼしなく受け取れるプログラムが書けるかもしれません。 送信と受信

ちなみに、下のプログラムを使って送受信し、取りこぼす事は結構あります・・。が。全文字受信することも多々あります。成功率7割ほどでしょうか。
学習で使ってるだけなので、取りこぼしについてはまずは考えないことにします。取りこぼしが困るなら、「文字列」で受け取らずに「文字」で受け取り、その受け取った「文字」でどんなメッセージかを判別つけるようにすれば、成功率は上がると思うので・・。
まああんまり細かいことは気にせずにやってます、めんどりです。

プログラム

/*シリアルポートsci0を使った通信(ディップで送信)*/ /*プログラム名・・・sci0_3_s.c*/ #include <h8/reg3067.h> //レジスタの定義 #include <string.h> #include <mes2.h> int main() { int fd,i,j,len,flag = 0,Data = 0; unsigned char b[] = "Mendori"; unsigned char c[] = "Happy!!!"; unsigned char d = '\0'; char *adr; P5DDR = 0xF0; P5PCR = 0x0F; //プルアップ while(1){ //下位4ビット入力 Data = P5DR; Data = Data & 0x0F; printf("%x",Data); //ディップスイッチが入ったら(送信) //ディップ1はスタートボタン if(Data == 0x0E){ while(1){ //下位4ビット入力 Data = P5DR; Data = Data & 0x0F; switch (Data){ //ディップ1 case 0x0E : break; //ディップ2 case 0x0D : adr = &b[0]; flag = 1; break; //ディップ3 case 0x0B : adr = &c[0]; flag = 1; break; //ディップ4 case 0x07 : adr = &d; flag = 1; break; } //switch if(flag != 0) break; } //while //自身のハイパーターミナルに書き出す j = strlen(adr); printf("%d文字送信中・・・",j); for(i=0;i<j+1;++i){ fd = open("com0",0); write(fd, adr, 1); close(fd); adr = ++adr; sleep(1000); } //for flag = 0; } //if } //while } //main

/*シリアルポートsci0を使った通信*/ /*(ディップで送信したのを受信)*/ /*プログラム名・・・sci0_3_r.c*/ #include <string.h> #include <mes2.h> int main() { int fd,i,len,r = 0; unsigned char lcd[82]; char *a; // ポインタに配列lcdの先頭アドレスを入れる a = lcd; // LCD画面の消去 fd = open("lcd0", 0); for(i=0;i<32;++i){   seek(fd, i);   fprintf(fd, " "); } close(fd); while(1){   do{     // 文字入力があるまで待つ     while(r == 0){       fd = open("com0",0); //ここのsleep(40)がポイント       sleep(40);       r = read(fd, a, 1);       close(fd);       printf("%d",r);     } //while //ここのsleep(12)もポイント     sleep(12);     r = 0;     // ポインタaを一要素分進める     a = ++a;   } //do   // 文字列の最後まで受け付ける   while(*(a-1)!= '\0');   //受信したらLCDに書き出す   fd = open("lcd0", 0);   write(fd, lcd, strlen(lcd));   close(fd);   len = strlen(lcd);   printf("\r\n%d文字受信しました",len);   a = lcd; } //while } //main

上2つのプログラム(上:sci0_3_s.c、下:sci0_3_r.c)のような書き方をしました。sci0_3_s.cが送信側のプログラムです。動きとしては、、送信側のボードのディップスイッチの1番をONしたあと、ディップの2もしくは3のどちらかをONします。1番のスイッチはまあ、なくても構わないんですが、送信が始まるよということを画面上ではっきり確認するためにつけています。
1番をONした後、2番をONしたらmendoriという7文字の文字列を送り始めます。3番であれば、Happy!!!という8文字の文字列を送り始めます。sci0_3_s.cプログラムの動きはそれだけです。
また、sci0_3_r.cは受信側のプログラムです。この動きは至ってシンプルです。sci0からの受信データがくるまで受信体勢をとり、受信したら配列に入れてポインタを一つ進めます。文字列の終端記号である\0を受け取ったら受信をやめて、自身の液晶に受け取ることの出来た文字列を表示します。
なお、この受信のプログラム中のsleep(40)とsleep(12)は特に大事です。ここの数字がちょっと異なるだけですぐに受信しなくなったりします。・・逆に言うとここの数字をもっといい数字に変えれば、もっと取りこぼしをしない動作をすると思われます。めんどくさいですが、お試しになりたい方は是非どうぞ。

このプログラムを使いたいという方はsci_0_3_s.csci0_3_r.cをそれぞれダウンロードしてお使いください。上のプログラムをコピー&ペーストしてコンパイルかけるとエラーの嵐になりますからご注意ください(空白の関係上)。

2つのマイコンボードでそれぞれ転送・実行をするには

さて、上で送信用のプログラムと受信用のプログラムを二つ紹介しました。ですが、これらを2台のマイコンボードにそれぞれ転送して、それぞれ実行できなければ、この実験をすることは出来ません。さて、それをするにはどうしたらよいのか・・。
今までは1台のマイコンボードだけで実験していたので、シリアルポートsci1を使ってハイパーターミナルからマイコンへIPアドレスを振ってやり、LANをつかってプログラムを転送し、sci1を経由してプログラムを実行していました。今回も同じように行うわけには行きません。パソコン(192.168.10.1)からLANケーブルは1本しか出てませんから・・。
そこで、今回はどちらか片方のマイコンボードに「LANを使ったプログラム転送」でなく、「シリアルポートsci1を使う転送方法」を取り入れます。・・これまで話題にはしませんでしたが、こういう方法があるんです。
それは、floadというH8へのプログラム転送プログラムです。なお、プログラムには著作権がありますので、今回私のサイトでの詳しい説明は避けます。詳細はh83069fさまをご覧ください。こちらのページの下のほうに「ram0にユーザーアプリをシリアル等で転送して、実行!」へのリンクがありますから、こちらにて勉強されるといいと思います。
なお、H8への転送プログラムはほかにもあります。もじのお部屋さまのrx/sxプログラムです。こちらは後日、作者さまの許可を取った上で、実験して私のサイトにて初心者向けの使い方を載せられたらなあと考えています。

さて、シリアルでのプログラム転送、今回はだいぶ「はしょり」ましたが、出来たと仮定して次の実際の画面に進みたいと思います

送信と受信

sci0_3_s.cとsci0_3_r.cから出来たプログラムたちはc:\mes\sci0_3フォルダにまとめていれました。それぞれにoファイル、elfファイル、cbaファイルが出来ているのがわかります。
ちなみに、今回私はアンダーバーを使ってファイル名を書いてますが、打ち込むときに大変なのでファイル名をもっと簡単なものに変えたほうが効率がいいと思います。何回も実行するときにわざわざアンダーバーを打つのはshiftキーを使わなくてはならないので大変でした・・。自己反省です。

sci0_3フォルダの中身

プログラムを準備したら、基本編7でインストールしたTeraTermを使っていきます。デスクトップ上のTeraTermへのショートカットをクリックして、起動します。パソコンのシリアルポートのどこに接続するかを聞いてくると思いますのでまずは送信側マイコンをつないでいるポートを選択します。今回の私の場合ですと、送信側マイコンはパソコンのシリアルポートCOM1につながっているのでCOM1を選びます。そしてマイコンボード上のタクトスイッチを押してリセットをかけると、下のような画面になると思います。

送信側マイコンをパソコンのcom1につないだ画面

それから、もう一度デスクトップ上のTeraTermショートカットをクリックします。今度は受信側のマイコンがパソコンにつながっているシリアルポートを選択、タクトスイッチを押します。私の場合はCOM2なので、下のようなCOM2に接続している画面が出てきます。

受信側マイコンをパソコンのcom2につないだ画面

デスクトップ上に二つのウィンドウを並べて表示しておきます。
このように、TeraTermは複数起動ができるようです。電話のマークの「ハイパーターミナル」は常に1つしか起動できないようですが、そこがTeraTermとの違いですね。
COM1COM2のウィンドウが立ち上がったら、まずはCOM2の受信側マイコンに対してプログラムを転送したいと思います。こちらCOM2に対してはこれまでどおりのLANを使ったプログラムの転送方法で転送します。図の1でping打って通ったら、2でTFTPサーバを起動し、プログラムのあるフォルダを指定しておきます。これまでの手順どおりですね。

COM2(受信側マイコン)のプログラムを転送 COM2(受信側マイコン)のプログラムを転送2 プログラム実行前のボードのようす

無事受信側のプログラムが転送できたら、実行を掛けてしまいます。すると下のように一定間隔で0を書き始めます。この0という数字は今何文字受信したかを示す数字です。送信側から文字が来てうまく受け取ることができたら1が表示されます。

COM2(受信側マイコン)のプログラムを実行

受信側プログラムがせっせと画面に0を印字している間に、今度はCOM1・・送信側のマイコンへのプログラムを転送します。
ここで先ほど触りだけ紹介したfloadを使った転送を行います。
とりあえず画面の状態遷都だけ載せておこうと思います。やり方は各自研究ください。

COM1(送信側マイコン)のプログラムを転送・・マクロ実行 COM1(送信側マイコン)のプログラムを転送・・マクロ実行2 COM1(送信側マイコン)のプログラムを転送・・マクロ実行3

さて、シリアルポートから送信側のマイコンへプログラムの転送が完了したら、やっとプログラムの実行です。下のような感じになります。高速でfという文字を画面に書き出していきます。これは動いてるよという証拠のために表示しています。

COM1(送信側マイコン)のプログラムを実行

これで受信側・送信側ともにプログラムの動いている状態にできました。すでに受信側も0を書き出しつつ動いています。
ここで、送信側マイコンのディップスイッチ1番をONします。

送信側マイコンのディップスイッチ1番をONする

1番をONすると、送信側の画面にeが表示されて、画面が静止します。これはこれから送信を始めるために、画面のf書き出しを止めています。

送信側の画面にeが表示されて画面が静止する

画面の静止が確認できたら、ディップスイッチ1番をOFFし、2番もしくは3番のディップスイッチをONしてみます。
すると送信側の画面に「○文字送信中・・・」という表示が出ます。下のような感じです。
今私は2番のスイッチをONしたので、mendoriの7文字が送信され始めました。

送信側の画面に○文字送信中・・・の表示が出る

それから、受信側の画面には0に交じってところどころで1が印字されていきます。
受信しているのを確認できたら、送信側でONしたディップスイッチ(今は2番)をOFFしておきます。

受信側の画面に1の表示が出る

受信が完了したら、下のように受信できた文字数を受信側の画面に表示します。同時に受信側のマイコンボードの液晶に受信した文字列を表示します。

受信側の画面に「○文字受信しました」の表示が出る 受信側の液晶にに受信した文字列を表示する

受信し終わると、送信側・受信側ともに、それぞれ送信待ち体勢・受信待ち体勢に戻ります。
今回の実験の流れは以上のとおりです。
大変でしたが、マイコン同士で送受信できると達成感がありました。sleep()に頼らない制御をしたいものですが、初心者の第一歩としてはここからはじめてみるのは良いことなのではないかと感じました。
なお、今回の実験では送信→受信で終わりましたが、さらに受信したら「受信できたよ」という文字列を送信側に送り返す・・・なんてことも考えられます。実は、私それを昨日丸一日かけてやってみましたが、どうにもこうにもうまくいきません。受信側での受信まではうまくいきますが、そこから送信側に文字列を送り返すと、よくて1文字程度しか送信側で受信することができませんでした。これ以上sleepでなんとかしようとするのは無理があるのかもしれません。

次は10.LabVIEWとH8-3069ボード(H8から文字送信)です。>>