MENU

Raspberry Pi Zero WHとWindows10のBluetoothによるシリアル通信のテスト

2020 6/14
Raspberry Pi Zero WHとWindows10のBluetoothによるシリアル通信のテスト

Raspberry Pi Zero WHのBluetoothによるシリアル通信を行いましたので忘備録。

コマンドプロンプトからSSHで行いましたが、モニターつなげてのGUIでも可能です。

目次

Raspberry PiのBluetoothをオンにする

まずはRaspberry PiのBluetoothをオンにします。

下記コマンドを叩いてあげてください。

pi@raspberrypi:~ $ sudo bluetoothctl
bluetooth] power on
[bluetooth] discoverable on
[bluetooth] agent on
[bluetooth] default-agentAgent

discoverableってのがペアリングモードです。

Windows10とペアリングする

Windows10とペアリングしてあげます。

タスクアイコンの中からBluetoothを開いて「Bluetoothデバイスの追加」をクリックします。

そうすると「raspberrypi」と現れるので、クリックしてペアリングします。

これでBluetoothでWindows10とRaspberry Piが繋がりました。

最高。

SDPサーバーを用意する

SDPサーバーというものがあります。

SDPは、相手の機器がどのようなサービスをサポートしているのかを検索するのに利用されるプロトコルだそうですが、こういうことを聞くとなんのことかさっぱりわかりませんね。

これはBluetoothがどんな振る舞いをするかを繋がっている機器に伝えるようなものです。

今回ラズパイはシリアル通信を行う機器として振る舞うので、そういうことを伝えるための手段ですね。

pi@raspberrypi:~ $ sdptool browse local

とコマンドを入力。

Failed to connect to SDP server on FF:FF:FF:00:00:00: No such file or directory

上記のようなエラーが出るので、下記ファイルを編集します。

pi@raspberrypi:~ $ nano /etc/systemd/system/dbus-org.bluez.service

これで編集可能です。

ExecStart=/usr/lib/bluetooth/bluetoothd

と書かれている行に、「–compat」を追加します。

ExecStart=/usr/lib/bluetooth/bluetoothd --compat

完了したら、ファイルを再読み込みします。

pi@raspberrypi:~ $ sudo systemctl daemon-reload

もう一度SDPツールの確認を行います。

pi@raspberrypi:/ $ sdptool browse local

今度もエラーが出ます。

前回とは違うエラーで、今回はパーミッションというファイルの所有権のエラーになりますので、パーミッションを書き換えます。

pi@raspberrypi:/ $ sudo chmod 777 /var/run/sdp

もう一度SDPツールの確認を行うと、下記のようにずらーっと出てきますので、これが出ればOKということですね。

pi@raspberrypi:~ $ sdptool browse local
Browsing FF:FF:FF:00:00:00 ...
Service RecHandle: 0x10000
Service Class ID List:
  "PnP Information" (0x1200)
Profile Descriptor List:
  "PnP Information" (0x1200)
    Version: 0x0103

Browsing FF:FF:FF:00:00:00 ...
Service Search failed: Invalid argument
Service Name: AVRCP CT
Service RecHandle: 0x10001
Service Class ID List:
  "AV Remote" (0x110e)
  "AV Remote Controller" (0x110f)
Protocol Descriptor List:
  "L2CAP" (0x0100)
    PSM: 23
  "AVCTP" (0x0017)
    uint16: 0x0103
Profile Descriptor List:
  "AV Remote" (0x110e)
    Version: 0x0106

Service Name: AVRCP TG
Service RecHandle: 0x10002
Service Class ID List:
  "AV Remote Target" (0x110c)
Protocol Descriptor List:
  "L2CAP" (0x0100)
    PSM: 23
  "AVCTP" (0x0017)
    uint16: 0x0103
Profile Descriptor List:
  "AV Remote" (0x110e)
    Version: 0x0105

Service Name: Audio Source
Service RecHandle: 0x10003
Service Class ID List:
  "Audio Source" (0x110a)
Protocol Descriptor List:
  "L2CAP" (0x0100)
    PSM: 25
  "AVDTP" (0x0019)
    uint16: 0x0103
Profile Descriptor List:
  "Advanced Audio" (0x110d)
    Version: 0x0103

Service Name: Headset Voice gateway
Service RecHandle: 0x10004
Service Class ID List:
  "Headset Audio Gateway" (0x1112)
  "Generic Audio" (0x1203)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 12
Profile Descriptor List:
  "Headset" (0x1108)
    Version: 0x0102

Service Name: Hands-Free Voice gateway
Service RecHandle: 0x10005
Service Class ID List:
  "Handsfree Audio Gateway" (0x111f)
  "Generic Audio" (0x1203)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 13
Profile Descriptor List:
  "Handsfree" (0x111e)
    Version: 0x0107

SerialPortを追加する

はい、現在このような形式としてRaspberry PiとBluetooth接続したときのプロトコルが登録されています。

しかしながら、この中にはSerialPortがサービスとして登録されていませんので、登録してあげます。

pi@raspberrypi:~ $ sudo sdptool add --channel=22 SP

これでOKです。

もう一度SDPツールの確認を行ないます。

pi@raspberrypi:~ $ sdptool browse local
Browsing FF:FF:FF:00:00:00 ...
Service RecHandle: 0x10000
Service Class ID List:
  "PnP Information" (0x1200)
Profile Descriptor List:
  "PnP Information" (0x1200)
    Version: 0x0103

Browsing FF:FF:FF:00:00:00 ...
Service Search failed: Invalid argument
Service Name: AVRCP CT
Service RecHandle: 0x10001
Service Class ID List:
  "AV Remote" (0x110e)
  "AV Remote Controller" (0x110f)
Protocol Descriptor List:
  "L2CAP" (0x0100)
    PSM: 23
  "AVCTP" (0x0017)
    uint16: 0x0103
Profile Descriptor List:
  "AV Remote" (0x110e)
    Version: 0x0106

Service Name: AVRCP TG
Service RecHandle: 0x10002
Service Class ID List:
  "AV Remote Target" (0x110c)
Protocol Descriptor List:
  "L2CAP" (0x0100)
    PSM: 23
  "AVCTP" (0x0017)
    uint16: 0x0103
Profile Descriptor List:
  "AV Remote" (0x110e)
    Version: 0x0105

Service Name: Audio Source
Service RecHandle: 0x10003
Service Class ID List:
  "Audio Source" (0x110a)
Protocol Descriptor List:
  "L2CAP" (0x0100)
    PSM: 25
  "AVDTP" (0x0019)
    uint16: 0x0103
Profile Descriptor List:
  "Advanced Audio" (0x110d)
    Version: 0x0103

Service Name: Headset Voice gateway
Service RecHandle: 0x10004
Service Class ID List:
  "Headset Audio Gateway" (0x1112)
  "Generic Audio" (0x1203)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 12
Profile Descriptor List:
  "Headset" (0x1108)
    Version: 0x0102

Service Name: Hands-Free Voice gateway
Service RecHandle: 0x10005
Service Class ID List:
  "Handsfree Audio Gateway" (0x111f)
  "Generic Audio" (0x1203)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 13
Profile Descriptor List:
  "Handsfree" (0x111e)
    Version: 0x0107

Service Name: Serial Port
Service Description: COM Port
Service Provider: BlueZ
Service RecHandle: 0x10006
Service Class ID List:
  "Serial Port" (0x1101)
Protocol Descriptor List:
  "L2CAP" (0x0100)
  "RFCOMM" (0x0003)
    Channel: 22
Language Base Attr List:
  code_ISO639: 0x656e
  encoding:    0x6a
  base_offset: 0x100
Profile Descriptor List:
  "Serial Port" (0x1101)
    Version: 0x0100

78行目に

Service Name: Serial Portと言う表記が確認できました。

これでシリアルポートが使えるようになりました。

シリアル通信させてみる

シリアルポートが使えることになったので、いよいよ通信を行っていきます。

まずは、Raspberry Piを通信待ちにします。

pi@raspberrypi:~ $ sudo rfcomm listen /dev/rfcomm0 22
Waiting for connection on channel 22

channel22の接続待ちですよというような意味ですね。

それではWindows側でデバイスの設定を行ってあげます。

コントロール パネル → ハードウェアとサウンド →デバイスとプリンターで「raspberrypi」を右クリックしてプロパティをクリック。

サービスの中からシリアルポート(SPP)’Serial Port’にチェックが入っていることを確認する。横のCOM3というのはウインドウズが割り当てた任意のポート番号なので、数字だけ覚えておきます。

Tera Termというシリアル通信できるソフトウェアがあるのですが今回はこちらのソフトウェアで通信してみます。

シリアルを選択、ポートも先程と同じポートを選びOKをクリック。

無事繋がります。

更にラズベリーパイのターミナルを確認してみると、

pi@raspberrypi:~ $ sudo rfcomm listen /dev/rfcomm0 22
Waiting for connection on channel 22
Connection from 00:1B:DC:06:97:47 to /dev/rfcomm0
Press CTRL-C for hangup

「connection from ~ to /dev/rfcomm0」という表示が追加されているはずです。

これでシリアル接続できたということです。

Windowsからの文字入力でシリアル通信のテストを行う

まずはWindowsのTera Termで実際に文字を入力していきます。

何と入力しても大丈夫です。

ということで「Ken Furuta」とか入力してみます。

この時点では何も出てきません。

ラズパイ側で新しくターミナルを開き、

pi@raspberrypi:~ $ sudo cat /dev/rfcomm0

と入力すれば、無事Raspberry Pi側のターミナルウィンドウにに「Ken Furuta」の文字が表示されます。

Raspberry Pi側からの文字入力でウィンドウズ側に表示させる

ということで、Raspberry Pi側から文字表示をさせていきます。

pi@raspberrypi:~ $ sudo echo 37design.co.jp > /dev/rfcomm0

と入力すれば、Windows側のTera Termに37design.co.jpという文字が入力されているはずです。

これで双方向のシリアル通信ができたということです!

お疲れさまでした!

BluetoothによるRaspberry Piのシリアル通信成功

Bluetoothの有効化の方法やポートの意味なんかを色々と調べながら通信させるということは非常に勉強になります。

問題を一つ一つ、ごく小さなところから解決していくことにプログラミングの面白さってありますね。

ああ、ポートはこういう仕組みでできるんだということがだんだん理解できるようになります。

WindowsとRaspberry Piの通信ができただけでも非常に嬉しいものです。

今回はWindowsとの通信を行いましたが、もちろんMacなんかでも通信することも容易でしょう。

今後はこのシリアル通信に文字列を送信させるようなことを行っていく予定です。

この記事を書いた人

古田 健のアバター 古田 健 代表取締役

ウェブサイトつくったり、アプリ作ったりしています。
動画撮影・編集・グラフィックデザインとかもトータルでやってます。

最近Flutterによるアプリ開発をはじめました。
フロントエンド開発のレベルの底上げやってます。

目次
閉じる