Armadilloフォーラム

アドオンモジュールの操作を行うシリアル通信プログラムをC言語で実装する方法

kobayashi20200227

2020年10月5日 21時49分

お世話になっております。
現在、Armadillo用Wi-SUNアドオンモジュールWS-00(https://armadillo.atmark-techno.com/option-products/OP-AGA-WS00-00)におけるコマンド入力プログラムをC言語で作成予定です。
Python言語ではシリアル通信用のパッケージをインポートして実装したのですが、C言語ではどのようにコマンドをシリアル通信で入力するのか手法を教えていただけますでしょうか。
ざっとですが、関連性のありそうなのはシリアルエコーサーバーの記事
https://manual.atmark-techno.com/armadillo-guide/armadillo-guide-2_ja-3…
だと思うのですが、この部分を入力の文字をそのまま返すのではなく、アドオンモジュールの仕様に応じたコマンドを入力でき、それに応じた仕様の出力を表示させるプログラムをイメージしています。
ご対応のほどよろしくお願いいたします。

コメント

at_syunya.ohshio

2020年10月6日 13時36分

大塩です。

> Python言語ではシリアル通信用のパッケージをインポートして実装したのですが、C言語ではどのようにコマンドをシリアル通信で入力するのか手法を教えていただけますでしょうか。
> ざっとですが、関連性のありそうなのはシリアルエコーサーバーの記事
> https://manual.atmark-techno.com/armadillo-guide/armadillo-guide-2_ja-3…
> だと思うのですが、この部分を入力の文字をそのまま返すのではなく、アドオンモジュールの仕様に応じたコマンドを入力でき、それに応じた仕様の出力を表示させるプログラムをイメージしています。

以下Howtoのサンプルプログラムが参考になるかと思われます。
・Armadillo-IoT G3で「Bluetooth ワットチェッカー」から計測データを表示
https://armadillo.atmark-techno.com/howto/armadillo_rex-btwattch1

サンプルコードの「xwrite」関数でコマンドを送信していますので、
こちらと呼び出し元をご参考ください。

kobayashi20200227

2020年10月7日 17時55分

大塩様
回答ありがとうございます。
xwrite関数を拝見したところ、呼び出し元のcommunicate_command関数があり、communicate_command関数はBluetooth ワットチェッカー REX-BTWATTCH1の
各機能に応じたpld,buf,cmdを定義した機能関数から呼ばれているという流れでした。
ワットチェッカーのソフトウェアマニュアルなどはございますでしょうか。
また、xwrite関数は最終的にはシリアルエコーサンプルと同様にwrite関数を呼び出しています。
C言語初学者で申し訳ありませんが、この2つの違いを教えていただけないでしょうか。

ワットチェッカーwrite関数呼び出し部分
ret = write(fd, buf + len, count - len);
if (ret < 0) {
if (errno == EINTR && !terminated) {
ret = 0;
continue;
}
perror("write");
return ret;
}
}

シリアルエコーサーバーwrite関数呼び出し部分
/* すべてのデータを書き込むまでループ(終了シグナル発生で中断) */
for (wrlen = 0; wrlen < len && !terminated; wrlen += ret) {
/* シリアルポートに書き込み */
ret = write(serial_fd, buf + wrlen, len - wrlen);
if (ret < 0) {
if (errno == EINTR) {
/* シグナル発生時はリトライ */
ret = 0;
continue;
}
exitfail_errno("write");
}
}

ファイル ファイルの説明
serialechoserver.c シリアルエコーサーバーサンプルプログラム
wattchecker.c ワットチェッカーサンプルプログラム

at_syunya.ohshio

2020年10月8日 12時07分

大塩です。

> ワットチェッカーwrite関数呼び出し部分
> ret = write(fd, buf + len, count - len);
> if (ret < 0) {
> if (errno == EINTR && !terminated) {
> ret = 0;
> continue;
> }
> perror("write");
> return ret;
> }
> }
>
> シリアルエコーサーバーwrite関数呼び出し部分
> /* すべてのデータを書き込むまでループ(終了シグナル発生で中断) */
> for (wrlen = 0; wrlen < len && !terminated; wrlen += ret) {
> /* シリアルポートに書き込み */
> ret = write(serial_fd, buf + wrlen, len - wrlen);
> if (ret < 0) {
> if (errno == EINTR) {
> /* シグナル発生時はリトライ */
> ret = 0;
> continue;
> }
> exitfail_errno("write");
> }
> }
>

write() を用いて書き込みを行っている点では同じですが、
ワットチェッカー側では、書き込みを行った後に適切なレスポンスを受ける必要があるため、
write()とread()を実行する関数をwrapperとして実装しています。
はじめに頂いた実装したい内容にて、WS00の通信先に入力(write)後、レスポンスを出力(read)したいと記載されていたため
こちらをご紹介させていただきました。

書き込む内容はWS00と通信する末端機器の仕様によるため、書き込み内容はそちらをご確認ください。
ワットチェッカーでは、以下のような16進数からなる文字列を書き込んでいます。
以下に例を記載します。
・計測開始の場合
AA 0 600 02 00 [CRC]

[AA] : ヘッダ(固定値)
[02] : コマンドサイズ(Low byte)
[00] : コマンドサイズ(High byte)
[02] : 計測開始命令(Low byte)
[00] : 計測開始命令(High byte)
[CRC] : CRC値

at_syunya.ohshio

2020年10月8日 13時11分

大塩です。

実際にwriteしている文字列例の説明が間違っていました。
申し訳ありません。
以下が正しい計測開始時の例になります。

AA 06 00 02 00 [CRC]

[AA] : ヘッダ(固定値)
[06] : コマンドサイズ(Low byte)
[00] : コマンドサイズ(High byte)
[02] : 計測開始命令(Low byte)
[00] : 計測開始命令(High byte)
[CRC] : CRC値

以上です。