none
Bluetooth SPP の再接続について RRS feed

  • 質問

  • BluetoothのSPPでシリアル通信をするプログラムをvisual studioのC#で作成しています。

    PCに接続しているBluetoothの機器の電源を再起動等で電源を一度落とすとシリアル通信の接続が途切れてしまいます。

    PC側のプログラムも再起動するとまた接続できる様になるのですが自動で再接続させる事はできませんでしょうか?

    PC側のプログラムで

    serialPort1.Close();

    serialPort1.Open();

    をやってみましたが これだけではダメな様でOpenの方で「System.IO.IOException: 'セマフォがタイムアウトしました。」とエラーが表示されます。

    現在切断を検知して再接続させようとしていますが自動で再接続させる設定か何かあるのでしょうか?

    現在試しているプログラムは下記内容です。

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;

    namespace WindowsFormsApp1
    {
        using System.IO.Ports;
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }

            delegate void SetTextCallback(string text);
            private void Responsetxtbox2(string text)
            {
                if (textBox1.InvokeRequired)
                {
                    SetTextCallback d = new SetTextCallback(Responsetxtbox2);
                    Invoke(d, new object[] { text });
                }
                else
                {
                    textBox1.AppendText(text + "\n");
                }
            }
            private void button1_Click(object sender, EventArgs e)
            {
                serialPort1.BaudRate = 115200;
                serialPort1.Parity = Parity.None;
                serialPort1.DataBits = 8;
                serialPort1.StopBits = StopBits.One;
                serialPort1.Handshake = Handshake.None;
                serialPort1.PortName = portComboBox.Text;
                serialPort1.Open();
            }

            private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
            {
                while (serialPort1.BytesToRead > 0)
                {
                    Responsetxtbox2(serialPort1.ReadLine());
                }
            }

            private void Form1_Load(object sender, EventArgs e)
            {
                string[] ports = SerialPort.GetPortNames();
                foreach (string port in ports)
                {
                    portComboBox.Items.Add(port);
                }
                if (portComboBox.Items.Count > 0)
                    portComboBox.SelectedIndex = 0;
            }

            private void button2_Click(object sender, EventArgs e)
            {
                serialPort1.Close();
                serialPort1.Open();
            }
        }
    }

    2019年1月29日 14:25

すべての返信

  • 現在

    Bluetooth機器が再起動してから20秒たつとエラーが起きることなく

    serialPort1.Close();

    serialPort1.Open();

    で再接続出来る事が分かりました

    何故か20秒たってないとOpenがエラーになる様です。

    serialPort1.Close();

    させてIsOpenがtrueになるまでエラーを無視して

    serialPort1.Open();

    を実行させ続けるとbluetooth機器が再起動後20秒でOpenに成功し再接続が出来る様になりました。

    現在timerで19秒おきに再接続をさせる事でなんとか自動で接続が復帰する様になりましたが

    力技で再接続させているだけな為

    再接続に20秒もかかってしまいますし

    19秒おきの再接続と受信データのタイミングが重なると接続に異常がない時でも無駄にデータを取りこぼしてしまう可能性があります。(接続に異常がない場合は再接続はすぐに終了しますが取りこぼしてしまう可能性はあります。)

    本来の正しいやり方はどの様にすればよろしいのでしょうか?

    2019年1月29日 14:27
  • kazuki4321aaさん、こんにちは。フォーラムオペレーターのHarukaです。
    MSDNフォーラムにご投稿くださいましてありがとうございます。

    >現在切断を検知して再接続させようとしていますが自動で再接続させる設定か何かあるのでしょうか?
    →接続状態を検出して自動的に再接続したい場合は、タイマー制御をWinformsアプリケーションにドラッグすることをお勧めします。
    これは19秒ごとに接続状態を検出できます。
    以下のサンプルコードをご参照ください。

    private void Form11_Load(object sender, EventArgs e)

            {

                timer1.Start();

                timer1.Interval = 19000;

               string[] ports = SerialPort.GetPortNames();

                foreach (string port in ports)

                {

                    portComboBox.Items.Add(port);

                }

                if (portComboBox.Items.Count > 0)

                    portComboBox.SelectedIndex = 0;

            }

            privatevoidtimer1_Tick(objectsender, EventArgs e)

            {

                if(!serialPort1.IsOpen)

                {

                    //reconnect code here.

                }

            }

    どうぞよろしくお願いします。


    MSDN/ TechNet Community Support Haruka

    ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、
    ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~
    2019年2月1日 6:04
    モデレータ
  • フォーラムオペレーター Haruka様

    ご回答ありがとうございます。

    IsOpenですがBluetooth機器が再起動して繋がらない際はつながっていないのにも関わらずIsOpenはTrueのままですので現状IsOpenでの切断検知は出来ない状態です。

    現在は再接続から20秒後にPinChangedイベントが発生する事を見つけましたので現在はPinChangedのイベントで再接続をかけております。

    bluetooth機器が再起動後直ぐに再接続をかけるにはどの様にすればよろしいでしょうか。

    2019年2月11日 8:49
  • bluetoothのstack(driver)が作り出している仮想COMを相手にしている以上、bluetoothレベルの制御をすけるのは、どだい無理な話ではないでしょうか。
    代わりに、Bluetooth SOCKET(c#からだとwinsockのinteropになるのかな)とか、UWPであればWindows.Devices.Bluetooth.Rfcommあたりを相手にしてれれば話も変わるような気もしますが。
    (ただし、Windowsは7は諦めて、10でMS純正ドライバ用、くらいは覚悟する必要があったはず)

    jzkey

    2019年2月11日 19:03
  • kazuki4321aaさん、こんにちは。フォーラムオペレーターのHarukaです。
    ご返信頂きありがとうございます。

    .netには、Bluetoothが再起動ステータスを確認するためのライブラリはありません。 
    できる方法は何度も何度もBluetoothをチェックするためにタイマーを作ることです。

    どうぞよろしくお願いします。


    MSDN/ TechNet Community Support Haruka

    ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、
    ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~
    2019年2月14日 7:06
    モデレータ