質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.48%

  • JavaScript

    16957questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Node.js

    1933questions

    Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

  • シリアルポート

    47questions

    シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。

Node.jsでのシリアル通信で、送信したコマンドと受信データを1対1対応させるには

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 4
  • VIEW 4,584

neipia2

score 30

初心者ですので意味不明なこと言ってたり、勘違いもあるかもしれません。ご指摘ください。

Node.jsでirMagicianとシリアル通信をしようとしています。

コマンドを送信して、その結果を使うような処理をしたいのですが、 結果が返ってくるよりも先にコールバックが呼ばれてしまうようで、コールバック関数ではその結果を受け取れません。

コールバック関数でなくても、これがこのコマンドの返答だとわかるようになっていれば良いです。
ただ、返答が返って来てからしたい処理などもあるので、同期的な感じ?になっていてほしいです。

どうしたらいいでしょうか。ご教授お願いします。

コード
 
var serial = require('serialport').SerialPort;
serial = new serial('/dev/ttyACM0',{baudrate:9600});

serial.on('open',function(){
    serial.on('data',function(data){
        console.log('data : '+data);
    });
    serial.write('i,6\r\n',function(err){
        console.log('write \'i,6\'');
        console.log(err || 'no err');
    });
});

=======================
出力
=======================
write 'i,6'
no err
data : 0012

このようなことをしたいです
# -*- coding: utf-8 -*-
import serial
import time

ser = serial.Serial("/dev/ttyACM0", 9600, timeout = 1)
ser.readline()

ser.write("I,1\r\n")#赤外線信号の変化点 (L/Hの切り替わり)の数
time.sleep(1.0)
recNumberStr = ser.readline()
recNumber = int(recNumberStr, 16)

irMagicianのコマンドとそのレスポンス

意味がよく分からないところなどありましたら指摘してください
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+2

serial.write(callback)は非同期呼び出しです。呼び出した結果データを受信したらdataイベントで受け取れるのではないでしょうか?なので、この動きはserialportというライブラリとしては意図した通りに動いています。

参考: serial.write() にはNote: The write operation is non-blocking. と書かれています。non-blockingなので、非同期呼び出しです。


 送信コマンドとデータ受信を1対1にする例


単純に考えれば下記のように後で実行したいコマンドのまとまりを関数にして行く方法でしょうか。いわゆるCallback地獄なので、Promiseを使うと幸せになりそうですね。
var serial = require('serialport').SerialPort;
serial = new serial('/dev/ttyACM0',{baudrate:9600});

var initialize = function(next){
    serial.write('i,6\r\n',function(err){
          serial.on('data',function(data){
            console.log('data : '+data);
            next();
        });
        console.log('write \'i,6\'');
        console.log(err || 'no err');
    });
}

var nextCommand = function(next){
    serial.write('i,1\r\n',function(err){
          serial.on('data',function(data){
            console.log('data : '+data);
            next();
        });
        console.log('write \'i,1\'');
        console.log(err || 'no err');
    });
}

serial.on('open',function(){
    initialize(nextCommand);
});

GitHubにはgo-irMagicianがあるので、node-irMagicianができるといいですね。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/08/19 23:52

    ご指摘ありがとうございます
    確かにそうですね...

    質問としては"送信コマンドと受信データを1対1対応させるにはどうすればいいのか"という方が正しいですね

    キャンセル

+1

drainを使用したらどうでしょうか?
試していませんが、すべての出力データがシリアルポートに送信されるまで待つとのことです。
https://github.com/voodootikigod/node-serialport/blob/master/examples/drain.js

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/08/19 21:54

    回答ありがとうございます。
    使ってみたのですが、"出力データがシリアルポートに送信されるまで待つ"だけで、向こうから返って来るものを受信するにはまた別の方法を考えないといけないかと...

    キャンセル

  • 2015/08/20 00:04

    すみません、待つだけでしたか。
    双方が送受信データをコントロールできるなら一意キーを一緒に送受信できれば同期的な動作は可能ですね。
    またはwrite後の最初のdataイベントは絶対に一対である仕組みであるならそれでも同期的な処理は可能ですね。
    どちらにしてもirMagicianで出来るかは分からないです。

    キャンセル

  • 2015/08/20 12:24

    ありがとうございます
    irMagicianからのデータはいじれない(いじれるとしても自分の技術的に無理)ので、後者の方が使えるか確認してみます

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.48%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • JavaScript

    16957questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Node.js

    1933questions

    Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

  • シリアルポート

    47questions

    シリアルポートは一度に一ビットごと移行される物理的なインターフェイスです。一般的には、9ピンのd-subコネクタであるRS-232を指します。